18dffb485Schristos /* GNU/Linux/MIPS specific low level interface, for the remote server for GDB. 2*64f917f5Schristos Copyright (C) 1995-2024 Free Software Foundation, Inc. 38dffb485Schristos 48dffb485Schristos This file is part of GDB. 58dffb485Schristos 68dffb485Schristos This program is free software; you can redistribute it and/or modify 78dffb485Schristos it under the terms of the GNU General Public License as published by 88dffb485Schristos the Free Software Foundation; either version 3 of the License, or 98dffb485Schristos (at your option) any later version. 108dffb485Schristos 118dffb485Schristos This program is distributed in the hope that it will be useful, 128dffb485Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 138dffb485Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 148dffb485Schristos GNU General Public License for more details. 158dffb485Schristos 168dffb485Schristos You should have received a copy of the GNU General Public License 178dffb485Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 188dffb485Schristos 198dffb485Schristos #include "linux-low.h" 208dffb485Schristos 218dffb485Schristos #include "nat/gdb_ptrace.h" 228dffb485Schristos #include <endian.h> 238dffb485Schristos 248dffb485Schristos #include "nat/mips-linux-watch.h" 258dffb485Schristos #include "gdb_proc_service.h" 268dffb485Schristos 278dffb485Schristos /* Linux target op definitions for the MIPS architecture. */ 288dffb485Schristos 298dffb485Schristos class mips_target : public linux_process_target 308dffb485Schristos { 318dffb485Schristos public: 328dffb485Schristos 338dffb485Schristos const regs_info *get_regs_info () override; 348dffb485Schristos 358dffb485Schristos const gdb_byte *sw_breakpoint_from_kind (int kind, int *size) override; 368dffb485Schristos 378dffb485Schristos bool supports_z_point_type (char z_type) override; 388dffb485Schristos 398dffb485Schristos protected: 408dffb485Schristos 418dffb485Schristos void low_arch_setup () override; 428dffb485Schristos 438dffb485Schristos bool low_cannot_fetch_register (int regno) override; 448dffb485Schristos 458dffb485Schristos bool low_cannot_store_register (int regno) override; 468dffb485Schristos 478dffb485Schristos bool low_fetch_register (regcache *regcache, int regno) override; 488dffb485Schristos 498dffb485Schristos bool low_supports_breakpoints () override; 508dffb485Schristos 518dffb485Schristos CORE_ADDR low_get_pc (regcache *regcache) override; 528dffb485Schristos 538dffb485Schristos void low_set_pc (regcache *regcache, CORE_ADDR newpc) override; 548dffb485Schristos 558dffb485Schristos bool low_breakpoint_at (CORE_ADDR pc) override; 568dffb485Schristos 578dffb485Schristos int low_insert_point (raw_bkpt_type type, CORE_ADDR addr, 588dffb485Schristos int size, raw_breakpoint *bp) override; 598dffb485Schristos 608dffb485Schristos int low_remove_point (raw_bkpt_type type, CORE_ADDR addr, 618dffb485Schristos int size, raw_breakpoint *bp) override; 628dffb485Schristos 638dffb485Schristos bool low_stopped_by_watchpoint () override; 648dffb485Schristos 658dffb485Schristos CORE_ADDR low_stopped_data_address () override; 668dffb485Schristos 678dffb485Schristos void low_collect_ptrace_register (regcache *regcache, int regno, 688dffb485Schristos char *buf) override; 698dffb485Schristos 708dffb485Schristos void low_supply_ptrace_register (regcache *regcache, int regno, 718dffb485Schristos const char *buf) override; 728dffb485Schristos 738dffb485Schristos arch_process_info *low_new_process () override; 748dffb485Schristos 758dffb485Schristos void low_delete_process (arch_process_info *info) override; 768dffb485Schristos 778dffb485Schristos void low_new_thread (lwp_info *) override; 788dffb485Schristos 798dffb485Schristos void low_delete_thread (arch_lwp_info *) override; 808dffb485Schristos 818dffb485Schristos void low_new_fork (process_info *parent, process_info *child) override; 828dffb485Schristos 838dffb485Schristos void low_prepare_to_resume (lwp_info *lwp) override; 848dffb485Schristos }; 858dffb485Schristos 868dffb485Schristos /* The singleton target ops object. */ 878dffb485Schristos 888dffb485Schristos static mips_target the_mips_target; 898dffb485Schristos 908dffb485Schristos /* Defined in auto-generated file mips-linux.c. */ 918dffb485Schristos void init_registers_mips_linux (void); 928dffb485Schristos extern const struct target_desc *tdesc_mips_linux; 938dffb485Schristos 948dffb485Schristos /* Defined in auto-generated file mips-dsp-linux.c. */ 958dffb485Schristos void init_registers_mips_dsp_linux (void); 968dffb485Schristos extern const struct target_desc *tdesc_mips_dsp_linux; 978dffb485Schristos 988dffb485Schristos /* Defined in auto-generated file mips64-linux.c. */ 998dffb485Schristos void init_registers_mips64_linux (void); 1008dffb485Schristos extern const struct target_desc *tdesc_mips64_linux; 1018dffb485Schristos 1028dffb485Schristos /* Defined in auto-generated file mips64-dsp-linux.c. */ 1038dffb485Schristos void init_registers_mips64_dsp_linux (void); 1048dffb485Schristos extern const struct target_desc *tdesc_mips64_dsp_linux; 1058dffb485Schristos 1068dffb485Schristos #ifdef __mips64 1078dffb485Schristos #define tdesc_mips_linux tdesc_mips64_linux 1088dffb485Schristos #define tdesc_mips_dsp_linux tdesc_mips64_dsp_linux 1098dffb485Schristos #endif 1108dffb485Schristos 1118dffb485Schristos #ifndef PTRACE_GET_THREAD_AREA 1128dffb485Schristos #define PTRACE_GET_THREAD_AREA 25 1138dffb485Schristos #endif 1148dffb485Schristos 1158dffb485Schristos #ifdef HAVE_SYS_REG_H 1168dffb485Schristos #include <sys/reg.h> 1178dffb485Schristos #endif 1188dffb485Schristos 1198dffb485Schristos #define mips_num_regs 73 1208dffb485Schristos #define mips_dsp_num_regs 80 1218dffb485Schristos 1228dffb485Schristos #include <asm/ptrace.h> 1238dffb485Schristos 1248dffb485Schristos #ifndef DSP_BASE 1258dffb485Schristos #define DSP_BASE 71 1268dffb485Schristos #define DSP_CONTROL 77 1278dffb485Schristos #endif 1288dffb485Schristos 1298dffb485Schristos union mips_register 1308dffb485Schristos { 1318dffb485Schristos unsigned char buf[8]; 1328dffb485Schristos 1338dffb485Schristos /* Deliberately signed, for proper sign extension. */ 1348dffb485Schristos int reg32; 1358dffb485Schristos long long reg64; 1368dffb485Schristos }; 1378dffb485Schristos 1388dffb485Schristos /* Return the ptrace ``address'' of register REGNO. */ 1398dffb485Schristos 1408dffb485Schristos #define mips_base_regs \ 1418dffb485Schristos -1, 1, 2, 3, 4, 5, 6, 7, \ 1428dffb485Schristos 8, 9, 10, 11, 12, 13, 14, 15, \ 1438dffb485Schristos 16, 17, 18, 19, 20, 21, 22, 23, \ 1448dffb485Schristos 24, 25, 26, 27, 28, 29, 30, 31, \ 1458dffb485Schristos \ 1468dffb485Schristos -1, MMLO, MMHI, BADVADDR, CAUSE, PC, \ 1478dffb485Schristos \ 1488dffb485Schristos FPR_BASE, FPR_BASE + 1, FPR_BASE + 2, FPR_BASE + 3, \ 1498dffb485Schristos FPR_BASE + 4, FPR_BASE + 5, FPR_BASE + 6, FPR_BASE + 7, \ 1508dffb485Schristos FPR_BASE + 8, FPR_BASE + 9, FPR_BASE + 10, FPR_BASE + 11, \ 1518dffb485Schristos FPR_BASE + 12, FPR_BASE + 13, FPR_BASE + 14, FPR_BASE + 15, \ 1528dffb485Schristos FPR_BASE + 16, FPR_BASE + 17, FPR_BASE + 18, FPR_BASE + 19, \ 1538dffb485Schristos FPR_BASE + 20, FPR_BASE + 21, FPR_BASE + 22, FPR_BASE + 23, \ 1548dffb485Schristos FPR_BASE + 24, FPR_BASE + 25, FPR_BASE + 26, FPR_BASE + 27, \ 1558dffb485Schristos FPR_BASE + 28, FPR_BASE + 29, FPR_BASE + 30, FPR_BASE + 31, \ 1568dffb485Schristos FPC_CSR, FPC_EIR 1578dffb485Schristos 1588dffb485Schristos #define mips_dsp_regs \ 1598dffb485Schristos DSP_BASE, DSP_BASE + 1, DSP_BASE + 2, DSP_BASE + 3, \ 1608dffb485Schristos DSP_BASE + 4, DSP_BASE + 5, \ 1618dffb485Schristos DSP_CONTROL 1628dffb485Schristos 1638dffb485Schristos static int mips_regmap[mips_num_regs] = { 1648dffb485Schristos mips_base_regs, 1658dffb485Schristos 0 1668dffb485Schristos }; 1678dffb485Schristos 1688dffb485Schristos static int mips_dsp_regmap[mips_dsp_num_regs] = { 1698dffb485Schristos mips_base_regs, 1708dffb485Schristos mips_dsp_regs, 1718dffb485Schristos 0 1728dffb485Schristos }; 1738dffb485Schristos 1748dffb485Schristos /* DSP registers are not in any regset and can only be accessed 1758dffb485Schristos individually. */ 1768dffb485Schristos 1778dffb485Schristos static unsigned char mips_dsp_regset_bitmap[(mips_dsp_num_regs + 7) / 8] = { 1788dffb485Schristos 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x80 1798dffb485Schristos }; 1808dffb485Schristos 1818dffb485Schristos static int have_dsp = -1; 1828dffb485Schristos 1838dffb485Schristos /* Try peeking at an arbitrarily chosen DSP register and pick the available 1848dffb485Schristos user register set accordingly. */ 1858dffb485Schristos 1868dffb485Schristos static const struct target_desc * 1878dffb485Schristos mips_read_description (void) 1888dffb485Schristos { 1898dffb485Schristos if (have_dsp < 0) 1908dffb485Schristos { 1918dffb485Schristos int pid = lwpid_of (current_thread); 1928dffb485Schristos 1938dffb485Schristos errno = 0; 1948dffb485Schristos ptrace (PTRACE_PEEKUSER, pid, DSP_CONTROL, 0); 1958dffb485Schristos switch (errno) 1968dffb485Schristos { 1978dffb485Schristos case 0: 1988dffb485Schristos have_dsp = 1; 1998dffb485Schristos break; 2008dffb485Schristos case EIO: 2018dffb485Schristos have_dsp = 0; 2028dffb485Schristos break; 2038dffb485Schristos default: 2048dffb485Schristos perror_with_name ("ptrace"); 2058dffb485Schristos break; 2068dffb485Schristos } 2078dffb485Schristos } 2088dffb485Schristos 2098dffb485Schristos return have_dsp ? tdesc_mips_dsp_linux : tdesc_mips_linux; 2108dffb485Schristos } 2118dffb485Schristos 2128dffb485Schristos void 2138dffb485Schristos mips_target::low_arch_setup () 2148dffb485Schristos { 2158dffb485Schristos current_process ()->tdesc = mips_read_description (); 2168dffb485Schristos } 2178dffb485Schristos 2188dffb485Schristos /* Per-process arch-specific data we want to keep. */ 2198dffb485Schristos 2208dffb485Schristos struct arch_process_info 2218dffb485Schristos { 2228dffb485Schristos /* -1 if the kernel and/or CPU do not support watch registers. 2238dffb485Schristos 1 if watch_readback is valid and we can read style, num_valid 2248dffb485Schristos and the masks. 2258dffb485Schristos 0 if we need to read the watch_readback. */ 2268dffb485Schristos 2278dffb485Schristos int watch_readback_valid; 2288dffb485Schristos 2298dffb485Schristos /* Cached watch register read values. */ 2308dffb485Schristos 2318dffb485Schristos struct pt_watch_regs watch_readback; 2328dffb485Schristos 2338dffb485Schristos /* Current watchpoint requests for this process. */ 2348dffb485Schristos 2358dffb485Schristos struct mips_watchpoint *current_watches; 2368dffb485Schristos 2378dffb485Schristos /* The current set of watch register values for writing the 2388dffb485Schristos registers. */ 2398dffb485Schristos 2408dffb485Schristos struct pt_watch_regs watch_mirror; 2418dffb485Schristos }; 2428dffb485Schristos 2438dffb485Schristos /* Per-thread arch-specific data we want to keep. */ 2448dffb485Schristos 2458dffb485Schristos struct arch_lwp_info 2468dffb485Schristos { 2478dffb485Schristos /* Non-zero if our copy differs from what's recorded in the thread. */ 2488dffb485Schristos int watch_registers_changed; 2498dffb485Schristos }; 2508dffb485Schristos 2518dffb485Schristos /* From mips-linux-nat.c. */ 2528dffb485Schristos 2538dffb485Schristos /* Pseudo registers can not be read. ptrace does not provide a way to 2548dffb485Schristos read (or set) PS_REGNUM, and there's no point in reading or setting 2558dffb485Schristos ZERO_REGNUM, it's always 0. We also can not set BADVADDR, CAUSE, 2568dffb485Schristos or FCRIR via ptrace(). */ 2578dffb485Schristos 2588dffb485Schristos bool 2598dffb485Schristos mips_target::low_cannot_fetch_register (int regno) 2608dffb485Schristos { 2618dffb485Schristos const struct target_desc *tdesc; 2628dffb485Schristos 2638dffb485Schristos if (get_regs_info ()->usrregs->regmap[regno] == -1) 2648dffb485Schristos return true; 2658dffb485Schristos 2668dffb485Schristos tdesc = current_process ()->tdesc; 2678dffb485Schristos 2688dffb485Schristos /* On n32 we can't access 64-bit registers via PTRACE_PEEKUSR. */ 2698dffb485Schristos if (register_size (tdesc, regno) > sizeof (PTRACE_XFER_TYPE)) 2708dffb485Schristos return true; 2718dffb485Schristos 2728dffb485Schristos if (find_regno (tdesc, "r0") == regno) 2738dffb485Schristos return true; 2748dffb485Schristos 2758dffb485Schristos return false; 2768dffb485Schristos } 2778dffb485Schristos 2788dffb485Schristos bool 2798dffb485Schristos mips_target::low_cannot_store_register (int regno) 2808dffb485Schristos { 2818dffb485Schristos const struct target_desc *tdesc; 2828dffb485Schristos 2838dffb485Schristos if (get_regs_info ()->usrregs->regmap[regno] == -1) 2848dffb485Schristos return true; 2858dffb485Schristos 2868dffb485Schristos tdesc = current_process ()->tdesc; 2878dffb485Schristos 2888dffb485Schristos /* On n32 we can't access 64-bit registers via PTRACE_POKEUSR. */ 2898dffb485Schristos if (register_size (tdesc, regno) > sizeof (PTRACE_XFER_TYPE)) 2908dffb485Schristos return true; 2918dffb485Schristos 2928dffb485Schristos if (find_regno (tdesc, "r0") == regno) 2938dffb485Schristos return true; 2948dffb485Schristos 2958dffb485Schristos if (find_regno (tdesc, "cause") == regno) 2968dffb485Schristos return true; 2978dffb485Schristos 2988dffb485Schristos if (find_regno (tdesc, "badvaddr") == regno) 2998dffb485Schristos return true; 3008dffb485Schristos 3018dffb485Schristos if (find_regno (tdesc, "fir") == regno) 3028dffb485Schristos return true; 3038dffb485Schristos 3048dffb485Schristos return false; 3058dffb485Schristos } 3068dffb485Schristos 3078dffb485Schristos bool 3088dffb485Schristos mips_target::low_fetch_register (regcache *regcache, int regno) 3098dffb485Schristos { 3108dffb485Schristos const struct target_desc *tdesc = current_process ()->tdesc; 3118dffb485Schristos 3128dffb485Schristos if (find_regno (tdesc, "r0") == regno) 3138dffb485Schristos { 3148dffb485Schristos supply_register_zeroed (regcache, regno); 3158dffb485Schristos return true; 3168dffb485Schristos } 3178dffb485Schristos 3188dffb485Schristos return false; 3198dffb485Schristos } 3208dffb485Schristos 3218dffb485Schristos bool 3228dffb485Schristos mips_target::low_supports_breakpoints () 3238dffb485Schristos { 3248dffb485Schristos return true; 3258dffb485Schristos } 3268dffb485Schristos 3278dffb485Schristos CORE_ADDR 3288dffb485Schristos mips_target::low_get_pc (regcache *regcache) 3298dffb485Schristos { 3308dffb485Schristos union mips_register pc; 3318dffb485Schristos collect_register_by_name (regcache, "pc", pc.buf); 3328dffb485Schristos return register_size (regcache->tdesc, 0) == 4 ? pc.reg32 : pc.reg64; 3338dffb485Schristos } 3348dffb485Schristos 3358dffb485Schristos void 3368dffb485Schristos mips_target::low_set_pc (regcache *regcache, CORE_ADDR pc) 3378dffb485Schristos { 3388dffb485Schristos union mips_register newpc; 3398dffb485Schristos if (register_size (regcache->tdesc, 0) == 4) 3408dffb485Schristos newpc.reg32 = pc; 3418dffb485Schristos else 3428dffb485Schristos newpc.reg64 = pc; 3438dffb485Schristos 3448dffb485Schristos supply_register_by_name (regcache, "pc", newpc.buf); 3458dffb485Schristos } 3468dffb485Schristos 3478dffb485Schristos /* Correct in either endianness. */ 3488dffb485Schristos static const unsigned int mips_breakpoint = 0x0005000d; 3498dffb485Schristos #define mips_breakpoint_len 4 3508dffb485Schristos 3518dffb485Schristos /* Implementation of target ops method "sw_breakpoint_from_kind". */ 3528dffb485Schristos 3538dffb485Schristos const gdb_byte * 3548dffb485Schristos mips_target::sw_breakpoint_from_kind (int kind, int *size) 3558dffb485Schristos { 3568dffb485Schristos *size = mips_breakpoint_len; 3578dffb485Schristos return (const gdb_byte *) &mips_breakpoint; 3588dffb485Schristos } 3598dffb485Schristos 3608dffb485Schristos bool 3618dffb485Schristos mips_target::low_breakpoint_at (CORE_ADDR where) 3628dffb485Schristos { 3638dffb485Schristos unsigned int insn; 3648dffb485Schristos 3658dffb485Schristos read_memory (where, (unsigned char *) &insn, 4); 3668dffb485Schristos if (insn == mips_breakpoint) 3678dffb485Schristos return true; 3688dffb485Schristos 3698dffb485Schristos /* If necessary, recognize more trap instructions here. GDB only uses the 3708dffb485Schristos one. */ 3718dffb485Schristos return false; 3728dffb485Schristos } 3738dffb485Schristos 3748dffb485Schristos /* Mark the watch registers of lwp, represented by ENTRY, as changed. */ 3758dffb485Schristos 3768dffb485Schristos static void 3778dffb485Schristos update_watch_registers_callback (thread_info *thread) 3788dffb485Schristos { 3798dffb485Schristos struct lwp_info *lwp = get_thread_lwp (thread); 3808dffb485Schristos 3818dffb485Schristos /* The actual update is done later just before resuming the lwp, 3828dffb485Schristos we just mark that the registers need updating. */ 3838dffb485Schristos lwp->arch_private->watch_registers_changed = 1; 3848dffb485Schristos 3858dffb485Schristos /* If the lwp isn't stopped, force it to momentarily pause, so 3868dffb485Schristos we can update its watch registers. */ 3878dffb485Schristos if (!lwp->stopped) 3888dffb485Schristos linux_stop_lwp (lwp); 3898dffb485Schristos } 3908dffb485Schristos 3918dffb485Schristos /* This is the implementation of linux target ops method 3928dffb485Schristos low_new_process. */ 3938dffb485Schristos 3948dffb485Schristos arch_process_info * 3958dffb485Schristos mips_target::low_new_process () 3968dffb485Schristos { 3978dffb485Schristos struct arch_process_info *info = XCNEW (struct arch_process_info); 3988dffb485Schristos 3998dffb485Schristos return info; 4008dffb485Schristos } 4018dffb485Schristos 4028dffb485Schristos /* This is the implementation of linux target ops method 4038dffb485Schristos low_delete_process. */ 4048dffb485Schristos 4058dffb485Schristos void 4068dffb485Schristos mips_target::low_delete_process (arch_process_info *info) 4078dffb485Schristos { 4088dffb485Schristos xfree (info); 4098dffb485Schristos } 4108dffb485Schristos 4118dffb485Schristos /* This is the implementation of linux target ops method low_new_thread. 4128dffb485Schristos Mark the watch registers as changed, so the threads' copies will 4138dffb485Schristos be updated. */ 4148dffb485Schristos 4158dffb485Schristos void 4168dffb485Schristos mips_target::low_new_thread (lwp_info *lwp) 4178dffb485Schristos { 4188dffb485Schristos struct arch_lwp_info *info = XCNEW (struct arch_lwp_info); 4198dffb485Schristos 4208dffb485Schristos info->watch_registers_changed = 1; 4218dffb485Schristos 4228dffb485Schristos lwp->arch_private = info; 4238dffb485Schristos } 4248dffb485Schristos 4258dffb485Schristos /* Function to call when a thread is being deleted. */ 4268dffb485Schristos 4278dffb485Schristos void 4288dffb485Schristos mips_target::low_delete_thread (arch_lwp_info *arch_lwp) 4298dffb485Schristos { 4308dffb485Schristos xfree (arch_lwp); 4318dffb485Schristos } 4328dffb485Schristos 4338dffb485Schristos /* Create a new mips_watchpoint and add it to the list. */ 4348dffb485Schristos 4358dffb485Schristos static void 4368dffb485Schristos mips_add_watchpoint (struct arch_process_info *priv, CORE_ADDR addr, int len, 4378dffb485Schristos enum target_hw_bp_type watch_type) 4388dffb485Schristos { 4398dffb485Schristos struct mips_watchpoint *new_watch; 4408dffb485Schristos struct mips_watchpoint **pw; 4418dffb485Schristos 4428dffb485Schristos new_watch = XNEW (struct mips_watchpoint); 4438dffb485Schristos new_watch->addr = addr; 4448dffb485Schristos new_watch->len = len; 4458dffb485Schristos new_watch->type = watch_type; 4468dffb485Schristos new_watch->next = NULL; 4478dffb485Schristos 4488dffb485Schristos pw = &priv->current_watches; 4498dffb485Schristos while (*pw != NULL) 4508dffb485Schristos pw = &(*pw)->next; 4518dffb485Schristos *pw = new_watch; 4528dffb485Schristos } 4538dffb485Schristos 4548dffb485Schristos /* Hook to call when a new fork is attached. */ 4558dffb485Schristos 4568dffb485Schristos void 4578dffb485Schristos mips_target::low_new_fork (process_info *parent, 4588dffb485Schristos process_info *child) 4598dffb485Schristos { 4608dffb485Schristos struct arch_process_info *parent_private; 4618dffb485Schristos struct arch_process_info *child_private; 4628dffb485Schristos struct mips_watchpoint *wp; 4638dffb485Schristos 4648dffb485Schristos /* These are allocated by linux_add_process. */ 4658dffb485Schristos gdb_assert (parent->priv != NULL 4668dffb485Schristos && parent->priv->arch_private != NULL); 4678dffb485Schristos gdb_assert (child->priv != NULL 4688dffb485Schristos && child->priv->arch_private != NULL); 4698dffb485Schristos 4708dffb485Schristos /* Linux kernel before 2.6.33 commit 4718dffb485Schristos 72f674d203cd230426437cdcf7dd6f681dad8b0d 4728dffb485Schristos will inherit hardware debug registers from parent 4738dffb485Schristos on fork/vfork/clone. Newer Linux kernels create such tasks with 4748dffb485Schristos zeroed debug registers. 4758dffb485Schristos 4768dffb485Schristos GDB core assumes the child inherits the watchpoints/hw 4778dffb485Schristos breakpoints of the parent, and will remove them all from the 4788dffb485Schristos forked off process. Copy the debug registers mirrors into the 4798dffb485Schristos new process so that all breakpoints and watchpoints can be 4808dffb485Schristos removed together. The debug registers mirror will become zeroed 4818dffb485Schristos in the end before detaching the forked off process, thus making 4828dffb485Schristos this compatible with older Linux kernels too. */ 4838dffb485Schristos 4848dffb485Schristos parent_private = parent->priv->arch_private; 4858dffb485Schristos child_private = child->priv->arch_private; 4868dffb485Schristos 4878dffb485Schristos child_private->watch_readback_valid = parent_private->watch_readback_valid; 4888dffb485Schristos child_private->watch_readback = parent_private->watch_readback; 4898dffb485Schristos 4908dffb485Schristos for (wp = parent_private->current_watches; wp != NULL; wp = wp->next) 4918dffb485Schristos mips_add_watchpoint (child_private, wp->addr, wp->len, wp->type); 4928dffb485Schristos 4938dffb485Schristos child_private->watch_mirror = parent_private->watch_mirror; 4948dffb485Schristos } 4958dffb485Schristos /* This is the implementation of linux target ops method 4968dffb485Schristos low_prepare_to_resume. If the watch regs have changed, update the 4978dffb485Schristos thread's copies. */ 4988dffb485Schristos 4998dffb485Schristos void 5008dffb485Schristos mips_target::low_prepare_to_resume (lwp_info *lwp) 5018dffb485Schristos { 5028dffb485Schristos ptid_t ptid = ptid_of (get_lwp_thread (lwp)); 5038dffb485Schristos struct process_info *proc = find_process_pid (ptid.pid ()); 5048dffb485Schristos struct arch_process_info *priv = proc->priv->arch_private; 5058dffb485Schristos 5068dffb485Schristos if (lwp->arch_private->watch_registers_changed) 5078dffb485Schristos { 5088dffb485Schristos /* Only update the watch registers if we have set or unset a 5098dffb485Schristos watchpoint already. */ 5108dffb485Schristos if (mips_linux_watch_get_num_valid (&priv->watch_mirror) > 0) 5118dffb485Schristos { 5128dffb485Schristos /* Write the mirrored watch register values. */ 5138dffb485Schristos int tid = ptid.lwp (); 5148dffb485Schristos 5158dffb485Schristos if (-1 == ptrace (PTRACE_SET_WATCH_REGS, tid, 5168dffb485Schristos &priv->watch_mirror, NULL)) 5178dffb485Schristos perror_with_name ("Couldn't write watch register"); 5188dffb485Schristos } 5198dffb485Schristos 5208dffb485Schristos lwp->arch_private->watch_registers_changed = 0; 5218dffb485Schristos } 5228dffb485Schristos } 5238dffb485Schristos 5248dffb485Schristos bool 5258dffb485Schristos mips_target::supports_z_point_type (char z_type) 5268dffb485Schristos { 5278dffb485Schristos switch (z_type) 5288dffb485Schristos { 5298dffb485Schristos case Z_PACKET_WRITE_WP: 5308dffb485Schristos case Z_PACKET_READ_WP: 5318dffb485Schristos case Z_PACKET_ACCESS_WP: 5328dffb485Schristos return true; 5338dffb485Schristos default: 5348dffb485Schristos return false; 5358dffb485Schristos } 5368dffb485Schristos } 5378dffb485Schristos 5388dffb485Schristos /* This is the implementation of linux target ops method 5398dffb485Schristos low_insert_point. */ 5408dffb485Schristos 5418dffb485Schristos int 5428dffb485Schristos mips_target::low_insert_point (raw_bkpt_type type, CORE_ADDR addr, 5438dffb485Schristos int len, raw_breakpoint *bp) 5448dffb485Schristos { 5458dffb485Schristos struct process_info *proc = current_process (); 5468dffb485Schristos struct arch_process_info *priv = proc->priv->arch_private; 5478dffb485Schristos struct pt_watch_regs regs; 5488dffb485Schristos long lwpid; 5498dffb485Schristos enum target_hw_bp_type watch_type; 5508dffb485Schristos uint32_t irw; 5518dffb485Schristos 5528dffb485Schristos lwpid = lwpid_of (current_thread); 5538dffb485Schristos if (!mips_linux_read_watch_registers (lwpid, 5548dffb485Schristos &priv->watch_readback, 5558dffb485Schristos &priv->watch_readback_valid, 5568dffb485Schristos 0)) 5578dffb485Schristos return -1; 5588dffb485Schristos 5598dffb485Schristos if (len <= 0) 5608dffb485Schristos return -1; 5618dffb485Schristos 5628dffb485Schristos regs = priv->watch_readback; 5638dffb485Schristos /* Add the current watches. */ 5648dffb485Schristos mips_linux_watch_populate_regs (priv->current_watches, ®s); 5658dffb485Schristos 5668dffb485Schristos /* Now try to add the new watch. */ 5678dffb485Schristos watch_type = raw_bkpt_type_to_target_hw_bp_type (type); 5688dffb485Schristos irw = mips_linux_watch_type_to_irw (watch_type); 5698dffb485Schristos if (!mips_linux_watch_try_one_watch (®s, addr, len, irw)) 5708dffb485Schristos return -1; 5718dffb485Schristos 5728dffb485Schristos /* It fit. Stick it on the end of the list. */ 5738dffb485Schristos mips_add_watchpoint (priv, addr, len, watch_type); 5748dffb485Schristos 5758dffb485Schristos priv->watch_mirror = regs; 5768dffb485Schristos 5778dffb485Schristos /* Only update the threads of this process. */ 5788dffb485Schristos for_each_thread (proc->pid, update_watch_registers_callback); 5798dffb485Schristos 5808dffb485Schristos return 0; 5818dffb485Schristos } 5828dffb485Schristos 5838dffb485Schristos /* This is the implementation of linux target ops method 5848dffb485Schristos low_remove_point. */ 5858dffb485Schristos 5868dffb485Schristos int 5878dffb485Schristos mips_target::low_remove_point (raw_bkpt_type type, CORE_ADDR addr, 5888dffb485Schristos int len, raw_breakpoint *bp) 5898dffb485Schristos { 5908dffb485Schristos struct process_info *proc = current_process (); 5918dffb485Schristos struct arch_process_info *priv = proc->priv->arch_private; 5928dffb485Schristos 5938dffb485Schristos int deleted_one; 5948dffb485Schristos enum target_hw_bp_type watch_type; 5958dffb485Schristos 5968dffb485Schristos struct mips_watchpoint **pw; 5978dffb485Schristos struct mips_watchpoint *w; 5988dffb485Schristos 5998dffb485Schristos /* Search for a known watch that matches. Then unlink and free it. */ 6008dffb485Schristos watch_type = raw_bkpt_type_to_target_hw_bp_type (type); 6018dffb485Schristos deleted_one = 0; 6028dffb485Schristos pw = &priv->current_watches; 6038dffb485Schristos while ((w = *pw)) 6048dffb485Schristos { 6058dffb485Schristos if (w->addr == addr && w->len == len && w->type == watch_type) 6068dffb485Schristos { 6078dffb485Schristos *pw = w->next; 6088dffb485Schristos free (w); 6098dffb485Schristos deleted_one = 1; 6108dffb485Schristos break; 6118dffb485Schristos } 6128dffb485Schristos pw = &(w->next); 6138dffb485Schristos } 6148dffb485Schristos 6158dffb485Schristos if (!deleted_one) 6168dffb485Schristos return -1; /* We don't know about it, fail doing nothing. */ 6178dffb485Schristos 6188dffb485Schristos /* At this point watch_readback is known to be valid because we 6198dffb485Schristos could not have added the watch without reading it. */ 6208dffb485Schristos gdb_assert (priv->watch_readback_valid == 1); 6218dffb485Schristos 6228dffb485Schristos priv->watch_mirror = priv->watch_readback; 6238dffb485Schristos mips_linux_watch_populate_regs (priv->current_watches, 6248dffb485Schristos &priv->watch_mirror); 6258dffb485Schristos 6268dffb485Schristos /* Only update the threads of this process. */ 6278dffb485Schristos for_each_thread (proc->pid, update_watch_registers_callback); 6288dffb485Schristos 6298dffb485Schristos return 0; 6308dffb485Schristos } 6318dffb485Schristos 6328dffb485Schristos /* This is the implementation of linux target ops method 6338dffb485Schristos low_stopped_by_watchpoint. The watchhi R and W bits indicate 6348dffb485Schristos the watch register triggered. */ 6358dffb485Schristos 6368dffb485Schristos bool 6378dffb485Schristos mips_target::low_stopped_by_watchpoint () 6388dffb485Schristos { 6398dffb485Schristos struct process_info *proc = current_process (); 6408dffb485Schristos struct arch_process_info *priv = proc->priv->arch_private; 6418dffb485Schristos int n; 6428dffb485Schristos int num_valid; 6438dffb485Schristos long lwpid = lwpid_of (current_thread); 6448dffb485Schristos 6458dffb485Schristos if (!mips_linux_read_watch_registers (lwpid, 6468dffb485Schristos &priv->watch_readback, 6478dffb485Schristos &priv->watch_readback_valid, 6488dffb485Schristos 1)) 6498dffb485Schristos return 0; 6508dffb485Schristos 6518dffb485Schristos num_valid = mips_linux_watch_get_num_valid (&priv->watch_readback); 6528dffb485Schristos 6538dffb485Schristos for (n = 0; n < MAX_DEBUG_REGISTER && n < num_valid; n++) 6548dffb485Schristos if (mips_linux_watch_get_watchhi (&priv->watch_readback, n) 6558dffb485Schristos & (R_MASK | W_MASK)) 6568dffb485Schristos return true; 6578dffb485Schristos 6588dffb485Schristos return false; 6598dffb485Schristos } 6608dffb485Schristos 6618dffb485Schristos /* This is the implementation of linux target ops method 6628dffb485Schristos low_stopped_data_address. */ 6638dffb485Schristos 6648dffb485Schristos CORE_ADDR 6658dffb485Schristos mips_target::low_stopped_data_address () 6668dffb485Schristos { 6678dffb485Schristos struct process_info *proc = current_process (); 6688dffb485Schristos struct arch_process_info *priv = proc->priv->arch_private; 6698dffb485Schristos int n; 6708dffb485Schristos int num_valid; 6718dffb485Schristos long lwpid = lwpid_of (current_thread); 6728dffb485Schristos 6738dffb485Schristos /* On MIPS we don't know the low order 3 bits of the data address. 6748dffb485Schristos GDB does not support remote targets that can't report the 6758dffb485Schristos watchpoint address. So, make our best guess; return the starting 6768dffb485Schristos address of a watchpoint request which overlaps the one that 6778dffb485Schristos triggered. */ 6788dffb485Schristos 6798dffb485Schristos if (!mips_linux_read_watch_registers (lwpid, 6808dffb485Schristos &priv->watch_readback, 6818dffb485Schristos &priv->watch_readback_valid, 6828dffb485Schristos 0)) 6838dffb485Schristos return 0; 6848dffb485Schristos 6858dffb485Schristos num_valid = mips_linux_watch_get_num_valid (&priv->watch_readback); 6868dffb485Schristos 6878dffb485Schristos for (n = 0; n < MAX_DEBUG_REGISTER && n < num_valid; n++) 6888dffb485Schristos if (mips_linux_watch_get_watchhi (&priv->watch_readback, n) 6898dffb485Schristos & (R_MASK | W_MASK)) 6908dffb485Schristos { 6918dffb485Schristos CORE_ADDR t_low, t_hi; 6928dffb485Schristos int t_irw; 6938dffb485Schristos struct mips_watchpoint *watch; 6948dffb485Schristos 6958dffb485Schristos t_low = mips_linux_watch_get_watchlo (&priv->watch_readback, n); 6968dffb485Schristos t_irw = t_low & IRW_MASK; 6978dffb485Schristos t_hi = (mips_linux_watch_get_watchhi (&priv->watch_readback, n) 6988dffb485Schristos | IRW_MASK); 6998dffb485Schristos t_low &= ~(CORE_ADDR)t_hi; 7008dffb485Schristos 7018dffb485Schristos for (watch = priv->current_watches; 7028dffb485Schristos watch != NULL; 7038dffb485Schristos watch = watch->next) 7048dffb485Schristos { 7058dffb485Schristos CORE_ADDR addr = watch->addr; 7068dffb485Schristos CORE_ADDR last_byte = addr + watch->len - 1; 7078dffb485Schristos 7088dffb485Schristos if ((t_irw & mips_linux_watch_type_to_irw (watch->type)) == 0) 7098dffb485Schristos { 7108dffb485Schristos /* Different type. */ 7118dffb485Schristos continue; 7128dffb485Schristos } 7138dffb485Schristos /* Check for overlap of even a single byte. */ 7148dffb485Schristos if (last_byte >= t_low && addr <= t_low + t_hi) 7158dffb485Schristos return addr; 7168dffb485Schristos } 7178dffb485Schristos } 7188dffb485Schristos 7198dffb485Schristos /* Shouldn't happen. */ 7208dffb485Schristos return 0; 7218dffb485Schristos } 7228dffb485Schristos 7238dffb485Schristos /* Fetch the thread-local storage pointer for libthread_db. */ 7248dffb485Schristos 7258dffb485Schristos ps_err_e 7268dffb485Schristos ps_get_thread_area (struct ps_prochandle *ph, 7278dffb485Schristos lwpid_t lwpid, int idx, void **base) 7288dffb485Schristos { 7298dffb485Schristos if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) != 0) 7308dffb485Schristos return PS_ERR; 7318dffb485Schristos 7328dffb485Schristos /* IDX is the bias from the thread pointer to the beginning of the 7338dffb485Schristos thread descriptor. It has to be subtracted due to implementation 7348dffb485Schristos quirks in libthread_db. */ 7358dffb485Schristos *base = (void *) ((char *)*base - idx); 7368dffb485Schristos 7378dffb485Schristos return PS_OK; 7388dffb485Schristos } 7398dffb485Schristos 7408dffb485Schristos static void 7418dffb485Schristos mips_collect_register (struct regcache *regcache, 7428dffb485Schristos int use_64bit, int regno, union mips_register *reg) 7438dffb485Schristos { 7448dffb485Schristos union mips_register tmp_reg; 7458dffb485Schristos 7468dffb485Schristos if (use_64bit) 7478dffb485Schristos { 7488dffb485Schristos collect_register (regcache, regno, &tmp_reg.reg64); 7498dffb485Schristos *reg = tmp_reg; 7508dffb485Schristos } 7518dffb485Schristos else 7528dffb485Schristos { 7538dffb485Schristos collect_register (regcache, regno, &tmp_reg.reg32); 7548dffb485Schristos reg->reg64 = tmp_reg.reg32; 7558dffb485Schristos } 7568dffb485Schristos } 7578dffb485Schristos 7588dffb485Schristos static void 7598dffb485Schristos mips_supply_register (struct regcache *regcache, 7608dffb485Schristos int use_64bit, int regno, const union mips_register *reg) 7618dffb485Schristos { 7628dffb485Schristos int offset = 0; 7638dffb485Schristos 7648dffb485Schristos /* For big-endian 32-bit targets, ignore the high four bytes of each 7658dffb485Schristos eight-byte slot. */ 7668dffb485Schristos if (__BYTE_ORDER == __BIG_ENDIAN && !use_64bit) 7678dffb485Schristos offset = 4; 7688dffb485Schristos 7698dffb485Schristos supply_register (regcache, regno, reg->buf + offset); 7708dffb485Schristos } 7718dffb485Schristos 7728dffb485Schristos #ifdef HAVE_PTRACE_GETREGS 7738dffb485Schristos 7748dffb485Schristos static void 7758dffb485Schristos mips_collect_register_32bit (struct regcache *regcache, 7768dffb485Schristos int use_64bit, int regno, unsigned char *buf) 7778dffb485Schristos { 7788dffb485Schristos union mips_register tmp_reg; 7798dffb485Schristos int reg32; 7808dffb485Schristos 7818dffb485Schristos mips_collect_register (regcache, use_64bit, regno, &tmp_reg); 7828dffb485Schristos reg32 = tmp_reg.reg64; 7838dffb485Schristos memcpy (buf, ®32, 4); 7848dffb485Schristos } 7858dffb485Schristos 7868dffb485Schristos static void 7878dffb485Schristos mips_supply_register_32bit (struct regcache *regcache, 7888dffb485Schristos int use_64bit, int regno, const unsigned char *buf) 7898dffb485Schristos { 7908dffb485Schristos union mips_register tmp_reg; 7918dffb485Schristos int reg32; 7928dffb485Schristos 7938dffb485Schristos memcpy (®32, buf, 4); 7948dffb485Schristos tmp_reg.reg64 = reg32; 7958dffb485Schristos mips_supply_register (regcache, use_64bit, regno, &tmp_reg); 7968dffb485Schristos } 7978dffb485Schristos 7988dffb485Schristos static void 7998dffb485Schristos mips_fill_gregset (struct regcache *regcache, void *buf) 8008dffb485Schristos { 8018dffb485Schristos union mips_register *regset = (union mips_register *) buf; 8028dffb485Schristos int i, use_64bit; 8038dffb485Schristos const struct target_desc *tdesc = regcache->tdesc; 8048dffb485Schristos 8058dffb485Schristos use_64bit = (register_size (tdesc, 0) == 8); 8068dffb485Schristos 8078dffb485Schristos for (i = 1; i < 32; i++) 8088dffb485Schristos mips_collect_register (regcache, use_64bit, i, regset + i); 8098dffb485Schristos 8108dffb485Schristos mips_collect_register (regcache, use_64bit, 8118dffb485Schristos find_regno (tdesc, "lo"), regset + 32); 8128dffb485Schristos mips_collect_register (regcache, use_64bit, 8138dffb485Schristos find_regno (tdesc, "hi"), regset + 33); 8148dffb485Schristos mips_collect_register (regcache, use_64bit, 8158dffb485Schristos find_regno (tdesc, "pc"), regset + 34); 8168dffb485Schristos mips_collect_register (regcache, use_64bit, 8178dffb485Schristos find_regno (tdesc, "badvaddr"), regset + 35); 8188dffb485Schristos mips_collect_register (regcache, use_64bit, 8198dffb485Schristos find_regno (tdesc, "status"), regset + 36); 8208dffb485Schristos mips_collect_register (regcache, use_64bit, 8218dffb485Schristos find_regno (tdesc, "cause"), regset + 37); 8228dffb485Schristos 8238dffb485Schristos mips_collect_register (regcache, use_64bit, 8248dffb485Schristos find_regno (tdesc, "restart"), regset + 0); 8258dffb485Schristos } 8268dffb485Schristos 8278dffb485Schristos static void 8288dffb485Schristos mips_store_gregset (struct regcache *regcache, const void *buf) 8298dffb485Schristos { 8308dffb485Schristos const union mips_register *regset = (const union mips_register *) buf; 8318dffb485Schristos int i, use_64bit; 8328dffb485Schristos 8338dffb485Schristos use_64bit = (register_size (regcache->tdesc, 0) == 8); 8348dffb485Schristos 8358dffb485Schristos supply_register_by_name_zeroed (regcache, "r0"); 8368dffb485Schristos 8378dffb485Schristos for (i = 1; i < 32; i++) 8388dffb485Schristos mips_supply_register (regcache, use_64bit, i, regset + i); 8398dffb485Schristos 8408dffb485Schristos mips_supply_register (regcache, use_64bit, 8418dffb485Schristos find_regno (regcache->tdesc, "lo"), regset + 32); 8428dffb485Schristos mips_supply_register (regcache, use_64bit, 8438dffb485Schristos find_regno (regcache->tdesc, "hi"), regset + 33); 8448dffb485Schristos mips_supply_register (regcache, use_64bit, 8458dffb485Schristos find_regno (regcache->tdesc, "pc"), regset + 34); 8468dffb485Schristos mips_supply_register (regcache, use_64bit, 8478dffb485Schristos find_regno (regcache->tdesc, "badvaddr"), regset + 35); 8488dffb485Schristos mips_supply_register (regcache, use_64bit, 8498dffb485Schristos find_regno (regcache->tdesc, "status"), regset + 36); 8508dffb485Schristos mips_supply_register (regcache, use_64bit, 8518dffb485Schristos find_regno (regcache->tdesc, "cause"), regset + 37); 8528dffb485Schristos 8538dffb485Schristos mips_supply_register (regcache, use_64bit, 8548dffb485Schristos find_regno (regcache->tdesc, "restart"), regset + 0); 8558dffb485Schristos } 8568dffb485Schristos 8578dffb485Schristos static void 8588dffb485Schristos mips_fill_fpregset (struct regcache *regcache, void *buf) 8598dffb485Schristos { 8608dffb485Schristos union mips_register *regset = (union mips_register *) buf; 8618dffb485Schristos int i, use_64bit, first_fp, big_endian; 8628dffb485Schristos 8638dffb485Schristos use_64bit = (register_size (regcache->tdesc, 0) == 8); 8648dffb485Schristos first_fp = find_regno (regcache->tdesc, "f0"); 8658dffb485Schristos big_endian = (__BYTE_ORDER == __BIG_ENDIAN); 8668dffb485Schristos 8678dffb485Schristos /* See GDB for a discussion of this peculiar layout. */ 8688dffb485Schristos for (i = 0; i < 32; i++) 8698dffb485Schristos if (use_64bit) 8708dffb485Schristos collect_register (regcache, first_fp + i, regset[i].buf); 8718dffb485Schristos else 8728dffb485Schristos collect_register (regcache, first_fp + i, 8738dffb485Schristos regset[i & ~1].buf + 4 * (big_endian != (i & 1))); 8748dffb485Schristos 8758dffb485Schristos mips_collect_register_32bit (regcache, use_64bit, 8768dffb485Schristos find_regno (regcache->tdesc, "fcsr"), regset[32].buf); 8778dffb485Schristos mips_collect_register_32bit (regcache, use_64bit, 8788dffb485Schristos find_regno (regcache->tdesc, "fir"), 8798dffb485Schristos regset[32].buf + 4); 8808dffb485Schristos } 8818dffb485Schristos 8828dffb485Schristos static void 8838dffb485Schristos mips_store_fpregset (struct regcache *regcache, const void *buf) 8848dffb485Schristos { 8858dffb485Schristos const union mips_register *regset = (const union mips_register *) buf; 8868dffb485Schristos int i, use_64bit, first_fp, big_endian; 8878dffb485Schristos 8888dffb485Schristos use_64bit = (register_size (regcache->tdesc, 0) == 8); 8898dffb485Schristos first_fp = find_regno (regcache->tdesc, "f0"); 8908dffb485Schristos big_endian = (__BYTE_ORDER == __BIG_ENDIAN); 8918dffb485Schristos 8928dffb485Schristos /* See GDB for a discussion of this peculiar layout. */ 8938dffb485Schristos for (i = 0; i < 32; i++) 8948dffb485Schristos if (use_64bit) 8958dffb485Schristos supply_register (regcache, first_fp + i, regset[i].buf); 8968dffb485Schristos else 8978dffb485Schristos supply_register (regcache, first_fp + i, 8988dffb485Schristos regset[i & ~1].buf + 4 * (big_endian != (i & 1))); 8998dffb485Schristos 9008dffb485Schristos mips_supply_register_32bit (regcache, use_64bit, 9018dffb485Schristos find_regno (regcache->tdesc, "fcsr"), 9028dffb485Schristos regset[32].buf); 9038dffb485Schristos mips_supply_register_32bit (regcache, use_64bit, 9048dffb485Schristos find_regno (regcache->tdesc, "fir"), 9058dffb485Schristos regset[32].buf + 4); 9068dffb485Schristos } 9078dffb485Schristos #endif /* HAVE_PTRACE_GETREGS */ 9088dffb485Schristos 9098dffb485Schristos /* Take care of 32-bit registers with 64-bit ptrace, POKEUSER side. */ 9108dffb485Schristos 9118dffb485Schristos void 9128dffb485Schristos mips_target::low_collect_ptrace_register (regcache *regcache, int regno, 9138dffb485Schristos char *buf) 9148dffb485Schristos { 9158dffb485Schristos int use_64bit = sizeof (PTRACE_XFER_TYPE) == 8; 9168dffb485Schristos 9178dffb485Schristos if (use_64bit && register_size (regcache->tdesc, regno) == 4) 9188dffb485Schristos { 9198dffb485Schristos union mips_register reg; 9208dffb485Schristos 9218dffb485Schristos mips_collect_register (regcache, 0, regno, ®); 9228dffb485Schristos memcpy (buf, ®, sizeof (reg)); 9238dffb485Schristos } 9248dffb485Schristos else 9258dffb485Schristos collect_register (regcache, regno, buf); 9268dffb485Schristos } 9278dffb485Schristos 9288dffb485Schristos /* Take care of 32-bit registers with 64-bit ptrace, PEEKUSER side. */ 9298dffb485Schristos 9308dffb485Schristos void 9318dffb485Schristos mips_target::low_supply_ptrace_register (regcache *regcache, int regno, 9328dffb485Schristos const char *buf) 9338dffb485Schristos { 9348dffb485Schristos int use_64bit = sizeof (PTRACE_XFER_TYPE) == 8; 9358dffb485Schristos 9368dffb485Schristos if (use_64bit && register_size (regcache->tdesc, regno) == 4) 9378dffb485Schristos { 9388dffb485Schristos union mips_register reg; 9398dffb485Schristos 9408dffb485Schristos memcpy (®, buf, sizeof (reg)); 9418dffb485Schristos mips_supply_register (regcache, 0, regno, ®); 9428dffb485Schristos } 9438dffb485Schristos else 9448dffb485Schristos supply_register (regcache, regno, buf); 9458dffb485Schristos } 9468dffb485Schristos 9478dffb485Schristos static struct regset_info mips_regsets[] = { 9488dffb485Schristos #ifdef HAVE_PTRACE_GETREGS 9498dffb485Schristos { PTRACE_GETREGS, PTRACE_SETREGS, 0, 38 * 8, GENERAL_REGS, 9508dffb485Schristos mips_fill_gregset, mips_store_gregset }, 9518dffb485Schristos { PTRACE_GETFPREGS, PTRACE_SETFPREGS, 0, 33 * 8, FP_REGS, 9528dffb485Schristos mips_fill_fpregset, mips_store_fpregset }, 9538dffb485Schristos #endif /* HAVE_PTRACE_GETREGS */ 9548dffb485Schristos NULL_REGSET 9558dffb485Schristos }; 9568dffb485Schristos 9578dffb485Schristos static struct regsets_info mips_regsets_info = 9588dffb485Schristos { 9598dffb485Schristos mips_regsets, /* regsets */ 9608dffb485Schristos 0, /* num_regsets */ 9618dffb485Schristos NULL, /* disabled_regsets */ 9628dffb485Schristos }; 9638dffb485Schristos 9648dffb485Schristos static struct usrregs_info mips_dsp_usrregs_info = 9658dffb485Schristos { 9668dffb485Schristos mips_dsp_num_regs, 9678dffb485Schristos mips_dsp_regmap, 9688dffb485Schristos }; 9698dffb485Schristos 9708dffb485Schristos static struct usrregs_info mips_usrregs_info = 9718dffb485Schristos { 9728dffb485Schristos mips_num_regs, 9738dffb485Schristos mips_regmap, 9748dffb485Schristos }; 9758dffb485Schristos 9768dffb485Schristos static struct regs_info dsp_regs_info = 9778dffb485Schristos { 9788dffb485Schristos mips_dsp_regset_bitmap, 9798dffb485Schristos &mips_dsp_usrregs_info, 9808dffb485Schristos &mips_regsets_info 9818dffb485Schristos }; 9828dffb485Schristos 9838dffb485Schristos static struct regs_info myregs_info = 9848dffb485Schristos { 9858dffb485Schristos NULL, /* regset_bitmap */ 9868dffb485Schristos &mips_usrregs_info, 9878dffb485Schristos &mips_regsets_info 9888dffb485Schristos }; 9898dffb485Schristos 9908dffb485Schristos const regs_info * 9918dffb485Schristos mips_target::get_regs_info () 9928dffb485Schristos { 9938dffb485Schristos if (have_dsp) 9948dffb485Schristos return &dsp_regs_info; 9958dffb485Schristos else 9968dffb485Schristos return &myregs_info; 9978dffb485Schristos } 9988dffb485Schristos 9998dffb485Schristos /* The linux target ops object. */ 10008dffb485Schristos 10018dffb485Schristos linux_process_target *the_linux_target = &the_mips_target; 10028dffb485Schristos 10038dffb485Schristos void 10048dffb485Schristos initialize_low_arch (void) 10058dffb485Schristos { 10068dffb485Schristos /* Initialize the Linux target descriptions. */ 10078dffb485Schristos init_registers_mips_linux (); 10088dffb485Schristos init_registers_mips_dsp_linux (); 10098dffb485Schristos init_registers_mips64_linux (); 10108dffb485Schristos init_registers_mips64_dsp_linux (); 10118dffb485Schristos 10128dffb485Schristos initialize_regsets_info (&mips_regsets_info); 10138dffb485Schristos } 1014