GDBserver
|
00001 /* GNU/Linux/MIPS specific low level interface, for the remote server for GDB. 00002 Copyright (C) 1995-2013 Free Software Foundation, Inc. 00003 00004 This file is part of GDB. 00005 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 3 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00018 00019 #include "server.h" 00020 #include "linux-low.h" 00021 00022 #include <sys/ptrace.h> 00023 #include <endian.h> 00024 00025 #include "mips-linux-watch.h" 00026 #include "gdb_proc_service.h" 00027 00028 /* Defined in auto-generated file mips-linux.c. */ 00029 void init_registers_mips_linux (void); 00030 extern const struct target_desc *tdesc_mips_linux; 00031 00032 /* Defined in auto-generated file mips-dsp-linux.c. */ 00033 void init_registers_mips_dsp_linux (void); 00034 extern const struct target_desc *tdesc_mips_dsp_linux; 00035 00036 /* Defined in auto-generated file mips64-linux.c. */ 00037 void init_registers_mips64_linux (void); 00038 extern const struct target_desc *tdesc_mips64_linux; 00039 00040 /* Defined in auto-generated file mips64-dsp-linux.c. */ 00041 void init_registers_mips64_dsp_linux (void); 00042 extern const struct target_desc *tdesc_mips64_dsp_linux; 00043 00044 #ifdef __mips64 00045 #define tdesc_mips_linux tdesc_mips64_linux 00046 #define tdesc_mips_dsp_linux tdesc_mips64_dsp_linux 00047 #endif 00048 00049 #ifndef PTRACE_GET_THREAD_AREA 00050 #define PTRACE_GET_THREAD_AREA 25 00051 #endif 00052 00053 #ifdef HAVE_SYS_REG_H 00054 #include <sys/reg.h> 00055 #endif 00056 00057 #define mips_num_regs 73 00058 #define mips_dsp_num_regs 80 00059 00060 #include <asm/ptrace.h> 00061 00062 #ifndef DSP_BASE 00063 #define DSP_BASE 71 00064 #define DSP_CONTROL 77 00065 #endif 00066 00067 union mips_register 00068 { 00069 unsigned char buf[8]; 00070 00071 /* Deliberately signed, for proper sign extension. */ 00072 int reg32; 00073 long long reg64; 00074 }; 00075 00076 /* Return the ptrace ``address'' of register REGNO. */ 00077 00078 #define mips_base_regs \ 00079 -1, 1, 2, 3, 4, 5, 6, 7, \ 00080 8, 9, 10, 11, 12, 13, 14, 15, \ 00081 16, 17, 18, 19, 20, 21, 22, 23, \ 00082 24, 25, 26, 27, 28, 29, 30, 31, \ 00083 \ 00084 -1, MMLO, MMHI, BADVADDR, CAUSE, PC, \ 00085 \ 00086 FPR_BASE, FPR_BASE + 1, FPR_BASE + 2, FPR_BASE + 3, \ 00087 FPR_BASE + 4, FPR_BASE + 5, FPR_BASE + 6, FPR_BASE + 7, \ 00088 FPR_BASE + 8, FPR_BASE + 9, FPR_BASE + 10, FPR_BASE + 11, \ 00089 FPR_BASE + 12, FPR_BASE + 13, FPR_BASE + 14, FPR_BASE + 15, \ 00090 FPR_BASE + 16, FPR_BASE + 17, FPR_BASE + 18, FPR_BASE + 19, \ 00091 FPR_BASE + 20, FPR_BASE + 21, FPR_BASE + 22, FPR_BASE + 23, \ 00092 FPR_BASE + 24, FPR_BASE + 25, FPR_BASE + 26, FPR_BASE + 27, \ 00093 FPR_BASE + 28, FPR_BASE + 29, FPR_BASE + 30, FPR_BASE + 31, \ 00094 FPC_CSR, FPC_EIR 00095 00096 #define mips_dsp_regs \ 00097 DSP_BASE, DSP_BASE + 1, DSP_BASE + 2, DSP_BASE + 3, \ 00098 DSP_BASE + 4, DSP_BASE + 5, \ 00099 DSP_CONTROL 00100 00101 static int mips_regmap[mips_num_regs] = { 00102 mips_base_regs, 00103 0 00104 }; 00105 00106 static int mips_dsp_regmap[mips_dsp_num_regs] = { 00107 mips_base_regs, 00108 mips_dsp_regs, 00109 0 00110 }; 00111 00112 /* DSP registers are not in any regset and can only be accessed 00113 individually. */ 00114 00115 static unsigned char mips_dsp_regset_bitmap[(mips_dsp_num_regs + 7) / 8] = { 00116 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x80 00117 }; 00118 00119 static int have_dsp = -1; 00120 00121 /* Try peeking at an arbitrarily chosen DSP register and pick the available 00122 user register set accordingly. */ 00123 00124 static const struct target_desc * 00125 mips_read_description (void) 00126 { 00127 if (have_dsp < 0) 00128 { 00129 int pid = lwpid_of (get_thread_lwp (current_inferior)); 00130 00131 ptrace (PTRACE_PEEKUSER, pid, DSP_CONTROL, 0); 00132 switch (errno) 00133 { 00134 case 0: 00135 have_dsp = 1; 00136 break; 00137 case EIO: 00138 have_dsp = 0; 00139 break; 00140 default: 00141 perror_with_name ("ptrace"); 00142 break; 00143 } 00144 } 00145 00146 return have_dsp ? tdesc_mips_dsp_linux : tdesc_mips_linux; 00147 } 00148 00149 static void 00150 mips_arch_setup (void) 00151 { 00152 current_process ()->tdesc = mips_read_description (); 00153 } 00154 00155 static struct usrregs_info * 00156 get_usrregs_info (void) 00157 { 00158 const struct regs_info *regs_info = the_low_target.regs_info (); 00159 00160 return regs_info->usrregs; 00161 } 00162 00163 /* Per-process arch-specific data we want to keep. */ 00164 00165 struct arch_process_info 00166 { 00167 /* -1 if the kernel and/or CPU do not support watch registers. 00168 1 if watch_readback is valid and we can read style, num_valid 00169 and the masks. 00170 0 if we need to read the watch_readback. */ 00171 00172 int watch_readback_valid; 00173 00174 /* Cached watch register read values. */ 00175 00176 struct pt_watch_regs watch_readback; 00177 00178 /* Current watchpoint requests for this process. */ 00179 00180 struct mips_watchpoint *current_watches; 00181 00182 /* The current set of watch register values for writing the 00183 registers. */ 00184 00185 struct pt_watch_regs watch_mirror; 00186 }; 00187 00188 /* Per-thread arch-specific data we want to keep. */ 00189 00190 struct arch_lwp_info 00191 { 00192 /* Non-zero if our copy differs from what's recorded in the thread. */ 00193 int watch_registers_changed; 00194 }; 00195 00196 /* From mips-linux-nat.c. */ 00197 00198 /* Pseudo registers can not be read. ptrace does not provide a way to 00199 read (or set) PS_REGNUM, and there's no point in reading or setting 00200 ZERO_REGNUM. We also can not set BADVADDR, CAUSE, or FCRIR via 00201 ptrace(). */ 00202 00203 static int 00204 mips_cannot_fetch_register (int regno) 00205 { 00206 const struct target_desc *tdesc; 00207 00208 if (get_usrregs_info ()->regmap[regno] == -1) 00209 return 1; 00210 00211 tdesc = current_process ()->tdesc; 00212 00213 if (find_regno (tdesc, "r0") == regno) 00214 return 1; 00215 00216 return 0; 00217 } 00218 00219 static int 00220 mips_cannot_store_register (int regno) 00221 { 00222 const struct target_desc *tdesc; 00223 00224 if (get_usrregs_info ()->regmap[regno] == -1) 00225 return 1; 00226 00227 tdesc = current_process ()->tdesc; 00228 00229 if (find_regno (tdesc, "r0") == regno) 00230 return 1; 00231 00232 if (find_regno (tdesc, "cause") == regno) 00233 return 1; 00234 00235 if (find_regno (tdesc, "badvaddr") == regno) 00236 return 1; 00237 00238 if (find_regno (tdesc, "fir") == regno) 00239 return 1; 00240 00241 return 0; 00242 } 00243 00244 static CORE_ADDR 00245 mips_get_pc (struct regcache *regcache) 00246 { 00247 union mips_register pc; 00248 collect_register_by_name (regcache, "pc", pc.buf); 00249 return register_size (regcache->tdesc, 0) == 4 ? pc.reg32 : pc.reg64; 00250 } 00251 00252 static void 00253 mips_set_pc (struct regcache *regcache, CORE_ADDR pc) 00254 { 00255 union mips_register newpc; 00256 if (register_size (regcache->tdesc, 0) == 4) 00257 newpc.reg32 = pc; 00258 else 00259 newpc.reg64 = pc; 00260 00261 supply_register_by_name (regcache, "pc", newpc.buf); 00262 } 00263 00264 /* Correct in either endianness. */ 00265 static const unsigned int mips_breakpoint = 0x0005000d; 00266 #define mips_breakpoint_len 4 00267 00268 /* We only place breakpoints in empty marker functions, and thread locking 00269 is outside of the function. So rather than importing software single-step, 00270 we can just run until exit. */ 00271 static CORE_ADDR 00272 mips_reinsert_addr (void) 00273 { 00274 struct regcache *regcache = get_thread_regcache (current_inferior, 1); 00275 union mips_register ra; 00276 collect_register_by_name (regcache, "r31", ra.buf); 00277 return register_size (regcache->tdesc, 0) == 4 ? ra.reg32 : ra.reg64; 00278 } 00279 00280 static int 00281 mips_breakpoint_at (CORE_ADDR where) 00282 { 00283 unsigned int insn; 00284 00285 (*the_target->read_memory) (where, (unsigned char *) &insn, 4); 00286 if (insn == mips_breakpoint) 00287 return 1; 00288 00289 /* If necessary, recognize more trap instructions here. GDB only uses the 00290 one. */ 00291 return 0; 00292 } 00293 00294 /* Mark the watch registers of lwp, represented by ENTRY, as changed, 00295 if the lwp's process id is *PID_P. */ 00296 00297 static int 00298 update_watch_registers_callback (struct inferior_list_entry *entry, 00299 void *pid_p) 00300 { 00301 struct lwp_info *lwp = (struct lwp_info *) entry; 00302 int pid = *(int *) pid_p; 00303 00304 /* Only update the threads of this process. */ 00305 if (pid_of (lwp) == pid) 00306 { 00307 /* The actual update is done later just before resuming the lwp, 00308 we just mark that the registers need updating. */ 00309 lwp->arch_private->watch_registers_changed = 1; 00310 00311 /* If the lwp isn't stopped, force it to momentarily pause, so 00312 we can update its watch registers. */ 00313 if (!lwp->stopped) 00314 linux_stop_lwp (lwp); 00315 } 00316 00317 return 0; 00318 } 00319 00320 /* This is the implementation of linux_target_ops method 00321 new_process. */ 00322 00323 static struct arch_process_info * 00324 mips_linux_new_process (void) 00325 { 00326 struct arch_process_info *info = xcalloc (1, sizeof (*info)); 00327 00328 return info; 00329 } 00330 00331 /* This is the implementation of linux_target_ops method new_thread. 00332 Mark the watch registers as changed, so the threads' copies will 00333 be updated. */ 00334 00335 static struct arch_lwp_info * 00336 mips_linux_new_thread (void) 00337 { 00338 struct arch_lwp_info *info = xcalloc (1, sizeof (*info)); 00339 00340 info->watch_registers_changed = 1; 00341 00342 return info; 00343 } 00344 00345 /* This is the implementation of linux_target_ops method 00346 prepare_to_resume. If the watch regs have changed, update the 00347 thread's copies. */ 00348 00349 static void 00350 mips_linux_prepare_to_resume (struct lwp_info *lwp) 00351 { 00352 ptid_t ptid = ptid_of (lwp); 00353 struct process_info *proc = find_process_pid (ptid_get_pid (ptid)); 00354 struct arch_process_info *private = proc->private->arch_private; 00355 00356 if (lwp->arch_private->watch_registers_changed) 00357 { 00358 /* Only update the watch registers if we have set or unset a 00359 watchpoint already. */ 00360 if (mips_linux_watch_get_num_valid (&private->watch_mirror) > 0) 00361 { 00362 /* Write the mirrored watch register values. */ 00363 int tid = ptid_get_lwp (ptid); 00364 00365 if (-1 == ptrace (PTRACE_SET_WATCH_REGS, tid, 00366 &private->watch_mirror)) 00367 perror_with_name ("Couldn't write watch register"); 00368 } 00369 00370 lwp->arch_private->watch_registers_changed = 0; 00371 } 00372 } 00373 00374 /* Translate breakpoint type TYPE in rsp to 'enum target_hw_bp_type'. */ 00375 00376 static enum target_hw_bp_type 00377 rsp_bp_type_to_target_hw_bp_type (char type) 00378 { 00379 switch (type) 00380 { 00381 case '2': 00382 return hw_write; 00383 case '3': 00384 return hw_read; 00385 case '4': 00386 return hw_access; 00387 } 00388 00389 gdb_assert_not_reached ("unhandled RSP breakpoint type"); 00390 } 00391 00392 /* This is the implementation of linux_target_ops method 00393 insert_point. */ 00394 00395 static int 00396 mips_insert_point (char type, CORE_ADDR addr, int len) 00397 { 00398 struct process_info *proc = current_process (); 00399 struct arch_process_info *private = proc->private->arch_private; 00400 struct pt_watch_regs regs; 00401 struct mips_watchpoint *new_watch; 00402 struct mips_watchpoint **pw; 00403 int pid; 00404 long lwpid; 00405 enum target_hw_bp_type watch_type; 00406 uint32_t irw; 00407 00408 /* Breakpoint/watchpoint types: 00409 '0' - software-breakpoint (not supported) 00410 '1' - hardware-breakpoint (not supported) 00411 '2' - write watchpoint (supported) 00412 '3' - read watchpoint (supported) 00413 '4' - access watchpoint (supported). */ 00414 00415 if (type < '2' || type > '4') 00416 { 00417 /* Unsupported. */ 00418 return 1; 00419 } 00420 00421 lwpid = lwpid_of (get_thread_lwp (current_inferior)); 00422 if (!mips_linux_read_watch_registers (lwpid, 00423 &private->watch_readback, 00424 &private->watch_readback_valid, 00425 0)) 00426 return -1; 00427 00428 if (len <= 0) 00429 return -1; 00430 00431 regs = private->watch_readback; 00432 /* Add the current watches. */ 00433 mips_linux_watch_populate_regs (private->current_watches, ®s); 00434 00435 /* Now try to add the new watch. */ 00436 watch_type = rsp_bp_type_to_target_hw_bp_type (type); 00437 irw = mips_linux_watch_type_to_irw (watch_type); 00438 if (!mips_linux_watch_try_one_watch (®s, addr, len, irw)) 00439 return -1; 00440 00441 /* It fit. Stick it on the end of the list. */ 00442 new_watch = xmalloc (sizeof (struct mips_watchpoint)); 00443 new_watch->addr = addr; 00444 new_watch->len = len; 00445 new_watch->type = watch_type; 00446 new_watch->next = NULL; 00447 00448 pw = &private->current_watches; 00449 while (*pw != NULL) 00450 pw = &(*pw)->next; 00451 *pw = new_watch; 00452 00453 private->watch_mirror = regs; 00454 00455 /* Only update the threads of this process. */ 00456 pid = pid_of (proc); 00457 find_inferior (&all_lwps, update_watch_registers_callback, &pid); 00458 00459 return 0; 00460 } 00461 00462 /* This is the implementation of linux_target_ops method 00463 remove_point. */ 00464 00465 static int 00466 mips_remove_point (char type, CORE_ADDR addr, int len) 00467 { 00468 struct process_info *proc = current_process (); 00469 struct arch_process_info *private = proc->private->arch_private; 00470 00471 int deleted_one; 00472 int pid; 00473 enum target_hw_bp_type watch_type; 00474 00475 struct mips_watchpoint **pw; 00476 struct mips_watchpoint *w; 00477 00478 /* Breakpoint/watchpoint types: 00479 '0' - software-breakpoint (not supported) 00480 '1' - hardware-breakpoint (not supported) 00481 '2' - write watchpoint (supported) 00482 '3' - read watchpoint (supported) 00483 '4' - access watchpoint (supported). */ 00484 00485 if (type < '2' || type > '4') 00486 { 00487 /* Unsupported. */ 00488 return 1; 00489 } 00490 00491 /* Search for a known watch that matches. Then unlink and free it. */ 00492 watch_type = rsp_bp_type_to_target_hw_bp_type (type); 00493 deleted_one = 0; 00494 pw = &private->current_watches; 00495 while ((w = *pw)) 00496 { 00497 if (w->addr == addr && w->len == len && w->type == watch_type) 00498 { 00499 *pw = w->next; 00500 free (w); 00501 deleted_one = 1; 00502 break; 00503 } 00504 pw = &(w->next); 00505 } 00506 00507 if (!deleted_one) 00508 return -1; /* We don't know about it, fail doing nothing. */ 00509 00510 /* At this point watch_readback is known to be valid because we 00511 could not have added the watch without reading it. */ 00512 gdb_assert (private->watch_readback_valid == 1); 00513 00514 private->watch_mirror = private->watch_readback; 00515 mips_linux_watch_populate_regs (private->current_watches, 00516 &private->watch_mirror); 00517 00518 /* Only update the threads of this process. */ 00519 pid = pid_of (proc); 00520 find_inferior (&all_lwps, update_watch_registers_callback, &pid); 00521 return 0; 00522 } 00523 00524 /* This is the implementation of linux_target_ops method 00525 stopped_by_watchpoint. The watchhi R and W bits indicate 00526 the watch register triggered. */ 00527 00528 static int 00529 mips_stopped_by_watchpoint (void) 00530 { 00531 struct process_info *proc = current_process (); 00532 struct arch_process_info *private = proc->private->arch_private; 00533 int n; 00534 int num_valid; 00535 long lwpid = lwpid_of (get_thread_lwp (current_inferior)); 00536 00537 if (!mips_linux_read_watch_registers (lwpid, 00538 &private->watch_readback, 00539 &private->watch_readback_valid, 00540 1)) 00541 return 0; 00542 00543 num_valid = mips_linux_watch_get_num_valid (&private->watch_readback); 00544 00545 for (n = 0; n < MAX_DEBUG_REGISTER && n < num_valid; n++) 00546 if (mips_linux_watch_get_watchhi (&private->watch_readback, n) 00547 & (R_MASK | W_MASK)) 00548 return 1; 00549 00550 return 0; 00551 } 00552 00553 /* This is the implementation of linux_target_ops method 00554 stopped_data_address. */ 00555 00556 static CORE_ADDR 00557 mips_stopped_data_address (void) 00558 { 00559 struct process_info *proc = current_process (); 00560 struct arch_process_info *private = proc->private->arch_private; 00561 int n; 00562 int num_valid; 00563 long lwpid = lwpid_of (get_thread_lwp (current_inferior)); 00564 00565 /* On MIPS we don't know the low order 3 bits of the data address. 00566 GDB does not support remote targets that can't report the 00567 watchpoint address. So, make our best guess; return the starting 00568 address of a watchpoint request which overlaps the one that 00569 triggered. */ 00570 00571 if (!mips_linux_read_watch_registers (lwpid, 00572 &private->watch_readback, 00573 &private->watch_readback_valid, 00574 0)) 00575 return 0; 00576 00577 num_valid = mips_linux_watch_get_num_valid (&private->watch_readback); 00578 00579 for (n = 0; n < MAX_DEBUG_REGISTER && n < num_valid; n++) 00580 if (mips_linux_watch_get_watchhi (&private->watch_readback, n) 00581 & (R_MASK | W_MASK)) 00582 { 00583 CORE_ADDR t_low, t_hi; 00584 int t_irw; 00585 struct mips_watchpoint *watch; 00586 00587 t_low = mips_linux_watch_get_watchlo (&private->watch_readback, n); 00588 t_irw = t_low & IRW_MASK; 00589 t_hi = (mips_linux_watch_get_watchhi (&private->watch_readback, n) 00590 | IRW_MASK); 00591 t_low &= ~(CORE_ADDR)t_hi; 00592 00593 for (watch = private->current_watches; 00594 watch != NULL; 00595 watch = watch->next) 00596 { 00597 CORE_ADDR addr = watch->addr; 00598 CORE_ADDR last_byte = addr + watch->len - 1; 00599 00600 if ((t_irw & mips_linux_watch_type_to_irw (watch->type)) == 0) 00601 { 00602 /* Different type. */ 00603 continue; 00604 } 00605 /* Check for overlap of even a single byte. */ 00606 if (last_byte >= t_low && addr <= t_low + t_hi) 00607 return addr; 00608 } 00609 } 00610 00611 /* Shouldn't happen. */ 00612 return 0; 00613 } 00614 00615 /* Fetch the thread-local storage pointer for libthread_db. */ 00616 00617 ps_err_e 00618 ps_get_thread_area (const struct ps_prochandle *ph, 00619 lwpid_t lwpid, int idx, void **base) 00620 { 00621 if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) != 0) 00622 return PS_ERR; 00623 00624 /* IDX is the bias from the thread pointer to the beginning of the 00625 thread descriptor. It has to be subtracted due to implementation 00626 quirks in libthread_db. */ 00627 *base = (void *) ((char *)*base - idx); 00628 00629 return PS_OK; 00630 } 00631 00632 #ifdef HAVE_PTRACE_GETREGS 00633 00634 static void 00635 mips_collect_register (struct regcache *regcache, 00636 int use_64bit, int regno, union mips_register *reg) 00637 { 00638 union mips_register tmp_reg; 00639 00640 if (use_64bit) 00641 { 00642 collect_register (regcache, regno, &tmp_reg.reg64); 00643 *reg = tmp_reg; 00644 } 00645 else 00646 { 00647 collect_register (regcache, regno, &tmp_reg.reg32); 00648 reg->reg64 = tmp_reg.reg32; 00649 } 00650 } 00651 00652 static void 00653 mips_supply_register (struct regcache *regcache, 00654 int use_64bit, int regno, const union mips_register *reg) 00655 { 00656 int offset = 0; 00657 00658 /* For big-endian 32-bit targets, ignore the high four bytes of each 00659 eight-byte slot. */ 00660 if (__BYTE_ORDER == __BIG_ENDIAN && !use_64bit) 00661 offset = 4; 00662 00663 supply_register (regcache, regno, reg->buf + offset); 00664 } 00665 00666 static void 00667 mips_collect_register_32bit (struct regcache *regcache, 00668 int use_64bit, int regno, unsigned char *buf) 00669 { 00670 union mips_register tmp_reg; 00671 int reg32; 00672 00673 mips_collect_register (regcache, use_64bit, regno, &tmp_reg); 00674 reg32 = tmp_reg.reg64; 00675 memcpy (buf, ®32, 4); 00676 } 00677 00678 static void 00679 mips_supply_register_32bit (struct regcache *regcache, 00680 int use_64bit, int regno, const unsigned char *buf) 00681 { 00682 union mips_register tmp_reg; 00683 int reg32; 00684 00685 memcpy (®32, buf, 4); 00686 tmp_reg.reg64 = reg32; 00687 mips_supply_register (regcache, use_64bit, regno, &tmp_reg); 00688 } 00689 00690 static void 00691 mips_fill_gregset (struct regcache *regcache, void *buf) 00692 { 00693 union mips_register *regset = buf; 00694 int i, use_64bit; 00695 const struct target_desc *tdesc = regcache->tdesc; 00696 00697 use_64bit = (register_size (tdesc, 0) == 8); 00698 00699 for (i = 1; i < 32; i++) 00700 mips_collect_register (regcache, use_64bit, i, regset + i); 00701 00702 mips_collect_register (regcache, use_64bit, 00703 find_regno (tdesc, "lo"), regset + 32); 00704 mips_collect_register (regcache, use_64bit, 00705 find_regno (tdesc, "hi"), regset + 33); 00706 mips_collect_register (regcache, use_64bit, 00707 find_regno (tdesc, "pc"), regset + 34); 00708 mips_collect_register (regcache, use_64bit, 00709 find_regno (tdesc, "badvaddr"), regset + 35); 00710 mips_collect_register (regcache, use_64bit, 00711 find_regno (tdesc, "status"), regset + 36); 00712 mips_collect_register (regcache, use_64bit, 00713 find_regno (tdesc, "cause"), regset + 37); 00714 00715 mips_collect_register (regcache, use_64bit, 00716 find_regno (tdesc, "restart"), regset + 0); 00717 } 00718 00719 static void 00720 mips_store_gregset (struct regcache *regcache, const void *buf) 00721 { 00722 const union mips_register *regset = buf; 00723 int i, use_64bit; 00724 00725 use_64bit = (register_size (regcache->tdesc, 0) == 8); 00726 00727 for (i = 0; i < 32; i++) 00728 mips_supply_register (regcache, use_64bit, i, regset + i); 00729 00730 mips_supply_register (regcache, use_64bit, 00731 find_regno (regcache->tdesc, "lo"), regset + 32); 00732 mips_supply_register (regcache, use_64bit, 00733 find_regno (regcache->tdesc, "hi"), regset + 33); 00734 mips_supply_register (regcache, use_64bit, 00735 find_regno (regcache->tdesc, "pc"), regset + 34); 00736 mips_supply_register (regcache, use_64bit, 00737 find_regno (regcache->tdesc, "badvaddr"), regset + 35); 00738 mips_supply_register (regcache, use_64bit, 00739 find_regno (regcache->tdesc, "status"), regset + 36); 00740 mips_supply_register (regcache, use_64bit, 00741 find_regno (regcache->tdesc, "cause"), regset + 37); 00742 00743 mips_supply_register (regcache, use_64bit, 00744 find_regno (regcache->tdesc, "restart"), regset + 0); 00745 } 00746 00747 static void 00748 mips_fill_fpregset (struct regcache *regcache, void *buf) 00749 { 00750 union mips_register *regset = buf; 00751 int i, use_64bit, first_fp, big_endian; 00752 00753 use_64bit = (register_size (regcache->tdesc, 0) == 8); 00754 first_fp = find_regno (regcache->tdesc, "f0"); 00755 big_endian = (__BYTE_ORDER == __BIG_ENDIAN); 00756 00757 /* See GDB for a discussion of this peculiar layout. */ 00758 for (i = 0; i < 32; i++) 00759 if (use_64bit) 00760 collect_register (regcache, first_fp + i, regset[i].buf); 00761 else 00762 collect_register (regcache, first_fp + i, 00763 regset[i & ~1].buf + 4 * (big_endian != (i & 1))); 00764 00765 mips_collect_register_32bit (regcache, use_64bit, 00766 find_regno (regcache->tdesc, "fcsr"), regset[32].buf); 00767 mips_collect_register_32bit (regcache, use_64bit, 00768 find_regno (regcache->tdesc, "fir"), 00769 regset[32].buf + 4); 00770 } 00771 00772 static void 00773 mips_store_fpregset (struct regcache *regcache, const void *buf) 00774 { 00775 const union mips_register *regset = buf; 00776 int i, use_64bit, first_fp, big_endian; 00777 00778 use_64bit = (register_size (regcache->tdesc, 0) == 8); 00779 first_fp = find_regno (regcache->tdesc, "f0"); 00780 big_endian = (__BYTE_ORDER == __BIG_ENDIAN); 00781 00782 /* See GDB for a discussion of this peculiar layout. */ 00783 for (i = 0; i < 32; i++) 00784 if (use_64bit) 00785 supply_register (regcache, first_fp + i, regset[i].buf); 00786 else 00787 supply_register (regcache, first_fp + i, 00788 regset[i & ~1].buf + 4 * (big_endian != (i & 1))); 00789 00790 mips_supply_register_32bit (regcache, use_64bit, 00791 find_regno (regcache->tdesc, "fcsr"), 00792 regset[32].buf); 00793 mips_supply_register_32bit (regcache, use_64bit, 00794 find_regno (regcache->tdesc, "fir"), 00795 regset[32].buf + 4); 00796 } 00797 #endif /* HAVE_PTRACE_GETREGS */ 00798 00799 static struct regset_info mips_regsets[] = { 00800 #ifdef HAVE_PTRACE_GETREGS 00801 { PTRACE_GETREGS, PTRACE_SETREGS, 0, 38 * 8, GENERAL_REGS, 00802 mips_fill_gregset, mips_store_gregset }, 00803 { PTRACE_GETFPREGS, PTRACE_SETFPREGS, 0, 33 * 8, FP_REGS, 00804 mips_fill_fpregset, mips_store_fpregset }, 00805 #endif /* HAVE_PTRACE_GETREGS */ 00806 { 0, 0, 0, -1, -1, NULL, NULL } 00807 }; 00808 00809 static struct regsets_info mips_regsets_info = 00810 { 00811 mips_regsets, /* regsets */ 00812 0, /* num_regsets */ 00813 NULL, /* disabled_regsets */ 00814 }; 00815 00816 static struct usrregs_info mips_dsp_usrregs_info = 00817 { 00818 mips_dsp_num_regs, 00819 mips_dsp_regmap, 00820 }; 00821 00822 static struct usrregs_info mips_usrregs_info = 00823 { 00824 mips_num_regs, 00825 mips_regmap, 00826 }; 00827 00828 static struct regs_info dsp_regs_info = 00829 { 00830 mips_dsp_regset_bitmap, 00831 &mips_dsp_usrregs_info, 00832 &mips_regsets_info 00833 }; 00834 00835 static struct regs_info regs_info = 00836 { 00837 NULL, /* regset_bitmap */ 00838 &mips_usrregs_info, 00839 &mips_regsets_info 00840 }; 00841 00842 static const struct regs_info * 00843 mips_regs_info (void) 00844 { 00845 if (have_dsp) 00846 return &dsp_regs_info; 00847 else 00848 return ®s_info; 00849 } 00850 00851 struct linux_target_ops the_low_target = { 00852 mips_arch_setup, 00853 mips_regs_info, 00854 mips_cannot_fetch_register, 00855 mips_cannot_store_register, 00856 NULL, /* fetch_register */ 00857 mips_get_pc, 00858 mips_set_pc, 00859 (const unsigned char *) &mips_breakpoint, 00860 mips_breakpoint_len, 00861 mips_reinsert_addr, 00862 0, 00863 mips_breakpoint_at, 00864 mips_insert_point, 00865 mips_remove_point, 00866 mips_stopped_by_watchpoint, 00867 mips_stopped_data_address, 00868 NULL, 00869 NULL, 00870 NULL, /* siginfo_fixup */ 00871 mips_linux_new_process, 00872 mips_linux_new_thread, 00873 mips_linux_prepare_to_resume 00874 }; 00875 00876 void 00877 initialize_low_arch (void) 00878 { 00879 /* Initialize the Linux target descriptions. */ 00880 init_registers_mips_linux (); 00881 init_registers_mips_dsp_linux (); 00882 init_registers_mips64_linux (); 00883 init_registers_mips64_dsp_linux (); 00884 00885 initialize_regsets_info (&mips_regsets_info); 00886 }