xref: /netbsd-src/external/gpl3/gdb/dist/gdbserver/linux-arc-low.cc (revision 64f917f5a88990e32dd65fcd4348042fa7f852b9)
14b169a6bSchristos /* Target dependent code for the remote server for GNU/Linux ARC.
24b169a6bSchristos 
3*64f917f5Schristos    Copyright 2020-2024 Free Software Foundation, Inc.
44b169a6bSchristos 
54b169a6bSchristos    This file is part of GDB.
64b169a6bSchristos 
74b169a6bSchristos    This program is free software; you can redistribute it and/or modify
84b169a6bSchristos    it under the terms of the GNU General Public License as published by
94b169a6bSchristos    the Free Software Foundation; either version 3 of the License, or
104b169a6bSchristos    (at your option) any later version.
114b169a6bSchristos 
124b169a6bSchristos    This program is distributed in the hope that it will be useful,
134b169a6bSchristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
144b169a6bSchristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
154b169a6bSchristos    GNU General Public License for more details.
164b169a6bSchristos 
174b169a6bSchristos    You should have received a copy of the GNU General Public License
184b169a6bSchristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
194b169a6bSchristos 
204b169a6bSchristos #include "regdef.h"
214b169a6bSchristos #include "linux-low.h"
224b169a6bSchristos #include "tdesc.h"
234b169a6bSchristos #include "arch/arc.h"
244b169a6bSchristos 
254b169a6bSchristos #include <linux/elf.h>
264b169a6bSchristos #include <arpa/inet.h>
274b169a6bSchristos 
284b169a6bSchristos /* Linux starting with 4.12 supports NT_ARC_V2 note type, which adds R30,
294b169a6bSchristos    R58 and R59 registers.  */
304b169a6bSchristos #ifdef NT_ARC_V2
314b169a6bSchristos #define ARC_HAS_V2_REGSET
324b169a6bSchristos #endif
334b169a6bSchristos 
344b169a6bSchristos /* The encoding of the instruction "TRAP_S 1" (endianness agnostic).  */
354b169a6bSchristos #define TRAP_S_1_OPCODE	0x783e
364b169a6bSchristos #define TRAP_S_1_SIZE	2
374b169a6bSchristos 
384b169a6bSchristos /* Using a mere "uint16_t arc_linux_traps_s = TRAP_S_1_OPCODE" would
394b169a6bSchristos    work as well, because the endianness will end up correctly when
404b169a6bSchristos    the code is compiled for the same endianness as the target (see
414b169a6bSchristos    the notes for "low_breakpoint_at" in this file).  However, this
424b169a6bSchristos    illustrates how the __BIG_ENDIAN__ macro can be used to make
434b169a6bSchristos    easy-to-understand codes.  */
444b169a6bSchristos #if defined(__BIG_ENDIAN__)
454b169a6bSchristos /* 0x78, 0x3e.  */
464b169a6bSchristos static gdb_byte arc_linux_trap_s[TRAP_S_1_SIZE]
474b169a6bSchristos 	= {TRAP_S_1_OPCODE >> 8, TRAP_S_1_OPCODE & 0xFF};
484b169a6bSchristos #else
494b169a6bSchristos /* 0x3e, 0x78.  */
504b169a6bSchristos static gdb_byte arc_linux_trap_s[TRAP_S_1_SIZE]
514b169a6bSchristos 	= {TRAP_S_1_OPCODE && 0xFF, TRAP_S_1_OPCODE >> 8};
524b169a6bSchristos #endif
534b169a6bSchristos 
544b169a6bSchristos /* Linux target op definitions for the ARC architecture.
554b169a6bSchristos    Note for future: in case of adding the protected method low_get_next_pcs(),
564b169a6bSchristos    the public method supports_software_single_step() should be added to return
574b169a6bSchristos    "true".  */
584b169a6bSchristos 
594b169a6bSchristos class arc_target : public linux_process_target
604b169a6bSchristos {
614b169a6bSchristos public:
624b169a6bSchristos 
634b169a6bSchristos   const regs_info *get_regs_info () override;
644b169a6bSchristos 
654b169a6bSchristos   const gdb_byte *sw_breakpoint_from_kind (int kind, int *size) override;
664b169a6bSchristos 
674b169a6bSchristos protected:
684b169a6bSchristos 
694b169a6bSchristos   void low_arch_setup () override;
704b169a6bSchristos 
714b169a6bSchristos   bool low_cannot_fetch_register (int regno) override;
724b169a6bSchristos 
734b169a6bSchristos   bool low_cannot_store_register (int regno) override;
744b169a6bSchristos 
754b169a6bSchristos   bool low_supports_breakpoints () override;
764b169a6bSchristos 
774b169a6bSchristos   CORE_ADDR low_get_pc (regcache *regcache) override;
784b169a6bSchristos 
794b169a6bSchristos   void low_set_pc (regcache *regcache, CORE_ADDR newpc) override;
804b169a6bSchristos 
814b169a6bSchristos   bool low_breakpoint_at (CORE_ADDR where) override;
824b169a6bSchristos };
834b169a6bSchristos 
844b169a6bSchristos /* The singleton target ops object.  */
854b169a6bSchristos 
864b169a6bSchristos static arc_target the_arc_target;
874b169a6bSchristos 
884b169a6bSchristos bool
894b169a6bSchristos arc_target::low_supports_breakpoints ()
904b169a6bSchristos {
914b169a6bSchristos   return true;
924b169a6bSchristos }
934b169a6bSchristos 
944b169a6bSchristos CORE_ADDR
954b169a6bSchristos arc_target::low_get_pc (regcache *regcache)
964b169a6bSchristos {
974b169a6bSchristos   return linux_get_pc_32bit (regcache);
984b169a6bSchristos }
994b169a6bSchristos 
1004b169a6bSchristos void
1014b169a6bSchristos arc_target::low_set_pc (regcache *regcache, CORE_ADDR pc)
1024b169a6bSchristos {
1034b169a6bSchristos   linux_set_pc_32bit (regcache, pc);
1044b169a6bSchristos }
1054b169a6bSchristos 
1064b169a6bSchristos static const struct target_desc *
1074b169a6bSchristos arc_linux_read_description (void)
1084b169a6bSchristos {
1094b169a6bSchristos #ifdef __ARC700__
1104b169a6bSchristos   arc_arch_features features (4, ARC_ISA_ARCV1);
1114b169a6bSchristos #else
1124b169a6bSchristos   arc_arch_features features (4, ARC_ISA_ARCV2);
1134b169a6bSchristos #endif
1144b169a6bSchristos   target_desc_up tdesc = arc_create_target_description (features);
1154b169a6bSchristos 
1164b169a6bSchristos   static const char *expedite_regs[] = { "sp", "status32", nullptr };
1174b169a6bSchristos   init_target_desc (tdesc.get (), expedite_regs);
1184b169a6bSchristos 
1194b169a6bSchristos   return tdesc.release ();
1204b169a6bSchristos }
1214b169a6bSchristos 
1224b169a6bSchristos void
1234b169a6bSchristos arc_target::low_arch_setup ()
1244b169a6bSchristos {
1254b169a6bSchristos   current_process ()->tdesc = arc_linux_read_description ();
1264b169a6bSchristos }
1274b169a6bSchristos 
1284b169a6bSchristos bool
1294b169a6bSchristos arc_target::low_cannot_fetch_register (int regno)
1304b169a6bSchristos {
1314b169a6bSchristos   return (regno >= current_process ()->tdesc->reg_defs.size ());
1324b169a6bSchristos }
1334b169a6bSchristos 
1344b169a6bSchristos bool
1354b169a6bSchristos arc_target::low_cannot_store_register (int regno)
1364b169a6bSchristos {
1374b169a6bSchristos   return (regno >= current_process ()->tdesc->reg_defs.size ());
1384b169a6bSchristos }
1394b169a6bSchristos 
1404b169a6bSchristos /* This works for both endianness.  Below you see an illustration of how
1414b169a6bSchristos    the "trap_s 1" instruction encoded for both endianness in the memory
1424b169a6bSchristos    will end up as the TRAP_S_1_OPCODE constant:
1434b169a6bSchristos 
1444b169a6bSchristos    BE: 0x78 0x3e --> at INSN addr: 0x78 0x3e --> INSN = 0x783e
1454b169a6bSchristos    LE: 0x3e 0x78 --> at INSN addr: 0x3e 0x78 --> INSN = 0x783e
1464b169a6bSchristos 
1474b169a6bSchristos    One can employ "memcmp()" for comparing the arrays too.  */
1484b169a6bSchristos 
1494b169a6bSchristos bool
1504b169a6bSchristos arc_target::low_breakpoint_at (CORE_ADDR where)
1514b169a6bSchristos {
1524b169a6bSchristos   uint16_t insn;
1534b169a6bSchristos 
1544b169a6bSchristos   /* "the_target" global variable is the current object at hand.  */
1554b169a6bSchristos   this->read_memory (where, (gdb_byte *) &insn, TRAP_S_1_SIZE);
1564b169a6bSchristos   return (insn == TRAP_S_1_OPCODE);
1574b169a6bSchristos }
1584b169a6bSchristos 
1594b169a6bSchristos /* PTRACE_GETREGSET/NT_PRSTATUS and PTRACE_SETREGSET/NT_PRSTATUS work with
1604b169a6bSchristos    regsets in a struct, "user_regs_struct", defined in the
1614b169a6bSchristos    linux/arch/arc/include/uapi/asm/ptrace.h header.  This code supports
1624b169a6bSchristos    ARC Linux ABI v3 and v4.  */
1634b169a6bSchristos 
1644b169a6bSchristos /* Populate a ptrace NT_PRSTATUS regset from a regcache.
1654b169a6bSchristos 
1664b169a6bSchristos    This appears to be a unique approach to populating the buffer, but
1674b169a6bSchristos    being name, rather than offset based, it is robust to future API
1684b169a6bSchristos    changes, as there is no need to create a regmap of registers in the
1694b169a6bSchristos    user_regs_struct.  */
1704b169a6bSchristos 
1714b169a6bSchristos static void
1724b169a6bSchristos arc_fill_gregset (struct regcache *regcache, void *buf)
1734b169a6bSchristos {
1744b169a6bSchristos   struct user_regs_struct *regbuf = (struct user_regs_struct *) buf;
1754b169a6bSchristos 
1764b169a6bSchristos   /* Core registers.  */
1774b169a6bSchristos   collect_register_by_name (regcache, "r0", &(regbuf->scratch.r0));
1784b169a6bSchristos   collect_register_by_name (regcache, "r1", &(regbuf->scratch.r1));
1794b169a6bSchristos   collect_register_by_name (regcache, "r2", &(regbuf->scratch.r2));
1804b169a6bSchristos   collect_register_by_name (regcache, "r3", &(regbuf->scratch.r3));
1814b169a6bSchristos   collect_register_by_name (regcache, "r4", &(regbuf->scratch.r4));
1824b169a6bSchristos   collect_register_by_name (regcache, "r5", &(regbuf->scratch.r5));
1834b169a6bSchristos   collect_register_by_name (regcache, "r6", &(regbuf->scratch.r6));
1844b169a6bSchristos   collect_register_by_name (regcache, "r7", &(regbuf->scratch.r7));
1854b169a6bSchristos   collect_register_by_name (regcache, "r8", &(regbuf->scratch.r8));
1864b169a6bSchristos   collect_register_by_name (regcache, "r9", &(regbuf->scratch.r9));
1874b169a6bSchristos   collect_register_by_name (regcache, "r10", &(regbuf->scratch.r10));
1884b169a6bSchristos   collect_register_by_name (regcache, "r11", &(regbuf->scratch.r11));
1894b169a6bSchristos   collect_register_by_name (regcache, "r12", &(regbuf->scratch.r12));
1904b169a6bSchristos   collect_register_by_name (regcache, "r13", &(regbuf->callee.r13));
1914b169a6bSchristos   collect_register_by_name (regcache, "r14", &(regbuf->callee.r14));
1924b169a6bSchristos   collect_register_by_name (regcache, "r15", &(regbuf->callee.r15));
1934b169a6bSchristos   collect_register_by_name (regcache, "r16", &(regbuf->callee.r16));
1944b169a6bSchristos   collect_register_by_name (regcache, "r17", &(regbuf->callee.r17));
1954b169a6bSchristos   collect_register_by_name (regcache, "r18", &(regbuf->callee.r18));
1964b169a6bSchristos   collect_register_by_name (regcache, "r19", &(regbuf->callee.r19));
1974b169a6bSchristos   collect_register_by_name (regcache, "r20", &(regbuf->callee.r20));
1984b169a6bSchristos   collect_register_by_name (regcache, "r21", &(regbuf->callee.r21));
1994b169a6bSchristos   collect_register_by_name (regcache, "r22", &(regbuf->callee.r22));
2004b169a6bSchristos   collect_register_by_name (regcache, "r23", &(regbuf->callee.r23));
2014b169a6bSchristos   collect_register_by_name (regcache, "r24", &(regbuf->callee.r24));
2024b169a6bSchristos   collect_register_by_name (regcache, "r25", &(regbuf->callee.r25));
2034b169a6bSchristos   collect_register_by_name (regcache, "gp", &(regbuf->scratch.gp));
2044b169a6bSchristos   collect_register_by_name (regcache, "fp", &(regbuf->scratch.fp));
2054b169a6bSchristos   collect_register_by_name (regcache, "sp", &(regbuf->scratch.sp));
2064b169a6bSchristos   collect_register_by_name (regcache, "blink", &(regbuf->scratch.blink));
2074b169a6bSchristos 
2084b169a6bSchristos   /* Loop registers.  */
2094b169a6bSchristos   collect_register_by_name (regcache, "lp_count", &(regbuf->scratch.lp_count));
2104b169a6bSchristos   collect_register_by_name (regcache, "lp_start", &(regbuf->scratch.lp_start));
2114b169a6bSchristos   collect_register_by_name (regcache, "lp_end", &(regbuf->scratch.lp_end));
2124b169a6bSchristos 
2134b169a6bSchristos   /* The current "pc" value must be written to "eret" (exception return
2144b169a6bSchristos      address) register, because that is the address that the kernel code
2154b169a6bSchristos      will jump back to after a breakpoint exception has been raised.
2164b169a6bSchristos      The "pc_stop" value is ignored by the genregs_set() in
2174b169a6bSchristos      linux/arch/arc/kernel/ptrace.c.  */
2184b169a6bSchristos   collect_register_by_name (regcache, "pc", &(regbuf->scratch.ret));
2194b169a6bSchristos 
2204b169a6bSchristos   /* Currently ARC Linux ptrace doesn't allow writes to status32 because
2214b169a6bSchristos      some of its bits are kernel mode-only and shoudn't be writable from
2224b169a6bSchristos      user-space.  Writing status32 from debugger could be useful, though,
223*64f917f5Schristos      so ability to write non-privileged bits will be added to kernel
2244b169a6bSchristos      sooner or later.  */
2254b169a6bSchristos 
2264b169a6bSchristos   /* BTA.  */
2274b169a6bSchristos   collect_register_by_name (regcache, "bta", &(regbuf->scratch.bta));
2284b169a6bSchristos }
2294b169a6bSchristos 
2304b169a6bSchristos /* Populate a regcache from a ptrace NT_PRSTATUS regset.  */
2314b169a6bSchristos 
2324b169a6bSchristos static void
2334b169a6bSchristos arc_store_gregset (struct regcache *regcache, const void *buf)
2344b169a6bSchristos {
2354b169a6bSchristos   const struct user_regs_struct *regbuf = (const struct user_regs_struct *) buf;
2364b169a6bSchristos 
2374b169a6bSchristos   /* Core registers.  */
2384b169a6bSchristos   supply_register_by_name (regcache, "r0", &(regbuf->scratch.r0));
2394b169a6bSchristos   supply_register_by_name (regcache, "r1", &(regbuf->scratch.r1));
2404b169a6bSchristos   supply_register_by_name (regcache, "r2", &(regbuf->scratch.r2));
2414b169a6bSchristos   supply_register_by_name (regcache, "r3", &(regbuf->scratch.r3));
2424b169a6bSchristos   supply_register_by_name (regcache, "r4", &(regbuf->scratch.r4));
2434b169a6bSchristos   supply_register_by_name (regcache, "r5", &(regbuf->scratch.r5));
2444b169a6bSchristos   supply_register_by_name (regcache, "r6", &(regbuf->scratch.r6));
2454b169a6bSchristos   supply_register_by_name (regcache, "r7", &(regbuf->scratch.r7));
2464b169a6bSchristos   supply_register_by_name (regcache, "r8", &(regbuf->scratch.r8));
2474b169a6bSchristos   supply_register_by_name (regcache, "r9", &(regbuf->scratch.r9));
2484b169a6bSchristos   supply_register_by_name (regcache, "r10", &(regbuf->scratch.r10));
2494b169a6bSchristos   supply_register_by_name (regcache, "r11", &(regbuf->scratch.r11));
2504b169a6bSchristos   supply_register_by_name (regcache, "r12", &(regbuf->scratch.r12));
2514b169a6bSchristos   supply_register_by_name (regcache, "r13", &(regbuf->callee.r13));
2524b169a6bSchristos   supply_register_by_name (regcache, "r14", &(regbuf->callee.r14));
2534b169a6bSchristos   supply_register_by_name (regcache, "r15", &(regbuf->callee.r15));
2544b169a6bSchristos   supply_register_by_name (regcache, "r16", &(regbuf->callee.r16));
2554b169a6bSchristos   supply_register_by_name (regcache, "r17", &(regbuf->callee.r17));
2564b169a6bSchristos   supply_register_by_name (regcache, "r18", &(regbuf->callee.r18));
2574b169a6bSchristos   supply_register_by_name (regcache, "r19", &(regbuf->callee.r19));
2584b169a6bSchristos   supply_register_by_name (regcache, "r20", &(regbuf->callee.r20));
2594b169a6bSchristos   supply_register_by_name (regcache, "r21", &(regbuf->callee.r21));
2604b169a6bSchristos   supply_register_by_name (regcache, "r22", &(regbuf->callee.r22));
2614b169a6bSchristos   supply_register_by_name (regcache, "r23", &(regbuf->callee.r23));
2624b169a6bSchristos   supply_register_by_name (regcache, "r24", &(regbuf->callee.r24));
2634b169a6bSchristos   supply_register_by_name (regcache, "r25", &(regbuf->callee.r25));
2644b169a6bSchristos   supply_register_by_name (regcache, "gp", &(regbuf->scratch.gp));
2654b169a6bSchristos   supply_register_by_name (regcache, "fp", &(regbuf->scratch.fp));
2664b169a6bSchristos   supply_register_by_name (regcache, "sp", &(regbuf->scratch.sp));
2674b169a6bSchristos   supply_register_by_name (regcache, "blink", &(regbuf->scratch.blink));
2684b169a6bSchristos 
2694b169a6bSchristos   /* Loop registers.  */
2704b169a6bSchristos   supply_register_by_name (regcache, "lp_count", &(regbuf->scratch.lp_count));
2714b169a6bSchristos   supply_register_by_name (regcache, "lp_start", &(regbuf->scratch.lp_start));
2724b169a6bSchristos   supply_register_by_name (regcache, "lp_end", &(regbuf->scratch.lp_end));
2734b169a6bSchristos 
2744b169a6bSchristos   /* The genregs_get() in linux/arch/arc/kernel/ptrace.c populates the
2754b169a6bSchristos      pseudo register "stop_pc" with the "efa" (exception fault address)
2764b169a6bSchristos      register.  This was deemed necessary, because the breakpoint
2774b169a6bSchristos      instruction, "trap_s 1", is a committing one; i.e. the "eret"
2784b169a6bSchristos      (exception return address) register will be pointing to the next
2794b169a6bSchristos      instruction, while "efa" points to the address that raised the
2804b169a6bSchristos      breakpoint.  */
2814b169a6bSchristos   supply_register_by_name (regcache, "pc", &(regbuf->stop_pc));
2824b169a6bSchristos   unsigned long pcl = regbuf->stop_pc & ~3L;
2834b169a6bSchristos   supply_register_by_name (regcache, "pcl", &pcl);
2844b169a6bSchristos 
2854b169a6bSchristos   /* Other auxilliary registers.  */
2864b169a6bSchristos   supply_register_by_name (regcache, "status32", &(regbuf->scratch.status32));
2874b169a6bSchristos 
2884b169a6bSchristos   /* BTA.  */
2894b169a6bSchristos   supply_register_by_name (regcache, "bta", &(regbuf->scratch.bta));
2904b169a6bSchristos }
2914b169a6bSchristos 
2924b169a6bSchristos #ifdef ARC_HAS_V2_REGSET
2934b169a6bSchristos 
2944b169a6bSchristos /* Look through a regcache's TDESC for a register named NAME.
2954b169a6bSchristos    If found, return true; false, otherwise.  */
2964b169a6bSchristos 
2974b169a6bSchristos static bool
2984b169a6bSchristos is_reg_name_available_p (const struct target_desc *tdesc,
2994b169a6bSchristos 			 const char *name)
3004b169a6bSchristos {
3014b169a6bSchristos   for (const gdb::reg &reg : tdesc->reg_defs)
3024b169a6bSchristos     if (strcmp (name, reg.name) == 0)
3034b169a6bSchristos       return true;
3044b169a6bSchristos   return false;
3054b169a6bSchristos }
3064b169a6bSchristos 
3074b169a6bSchristos /* Copy registers from regcache to user_regs_arcv2.  */
3084b169a6bSchristos 
3094b169a6bSchristos static void
3104b169a6bSchristos arc_fill_v2_regset (struct regcache *regcache, void *buf)
3114b169a6bSchristos {
3124b169a6bSchristos   struct user_regs_arcv2 *regbuf = (struct user_regs_arcv2 *) buf;
3134b169a6bSchristos 
3144b169a6bSchristos   if (is_reg_name_available_p (regcache->tdesc, "r30"))
3154b169a6bSchristos     collect_register_by_name (regcache, "r30", &(regbuf->r30));
3164b169a6bSchristos 
3174b169a6bSchristos   if (is_reg_name_available_p (regcache->tdesc, "r58"))
3184b169a6bSchristos     collect_register_by_name (regcache, "r58", &(regbuf->r58));
3194b169a6bSchristos 
3204b169a6bSchristos   if (is_reg_name_available_p (regcache->tdesc, "r59"))
3214b169a6bSchristos     collect_register_by_name (regcache, "r59", &(regbuf->r59));
3224b169a6bSchristos }
3234b169a6bSchristos 
3244b169a6bSchristos /* Copy registers from user_regs_arcv2 to regcache.  */
3254b169a6bSchristos 
3264b169a6bSchristos static void
3274b169a6bSchristos arc_store_v2_regset (struct regcache *regcache, const void *buf)
3284b169a6bSchristos {
3294b169a6bSchristos   struct user_regs_arcv2 *regbuf = (struct user_regs_arcv2 *) buf;
3304b169a6bSchristos 
3314b169a6bSchristos   if (is_reg_name_available_p (regcache->tdesc, "r30"))
3324b169a6bSchristos     supply_register_by_name (regcache, "r30", &(regbuf->r30));
3334b169a6bSchristos 
3344b169a6bSchristos   if (is_reg_name_available_p (regcache->tdesc, "r58"))
3354b169a6bSchristos     supply_register_by_name (regcache, "r58", &(regbuf->r58));
3364b169a6bSchristos 
3374b169a6bSchristos   if (is_reg_name_available_p (regcache->tdesc, "r59"))
3384b169a6bSchristos     supply_register_by_name (regcache, "r59", &(regbuf->r59));
3394b169a6bSchristos }
3404b169a6bSchristos 
3414b169a6bSchristos #endif
3424b169a6bSchristos 
3434b169a6bSchristos /* Fetch the thread-local storage pointer for libthread_db.  Note that
3444b169a6bSchristos    this function is not called from GDB, but is called from libthread_db.
3454b169a6bSchristos 
3464b169a6bSchristos    This is the same function as for other architectures, for example in
3474b169a6bSchristos    linux-arm-low.c.  */
3484b169a6bSchristos 
3494b169a6bSchristos ps_err_e
3504b169a6bSchristos ps_get_thread_area (struct ps_prochandle *ph, lwpid_t lwpid,
3514b169a6bSchristos 		    int idx, void **base)
3524b169a6bSchristos {
3534b169a6bSchristos   if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, nullptr, base) != 0)
3544b169a6bSchristos     return PS_ERR;
3554b169a6bSchristos 
3564b169a6bSchristos   /* IDX is the bias from the thread pointer to the beginning of the
3574b169a6bSchristos      thread descriptor.  It has to be subtracted due to implementation
3584b169a6bSchristos      quirks in libthread_db.  */
3594b169a6bSchristos   *base = (void *) ((char *) *base - idx);
3604b169a6bSchristos 
3614b169a6bSchristos   return PS_OK;
3624b169a6bSchristos }
3634b169a6bSchristos 
3644b169a6bSchristos static struct regset_info arc_regsets[] =
3654b169a6bSchristos {
3664b169a6bSchristos   { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PRSTATUS,
3674b169a6bSchristos     sizeof (struct user_regs_struct), GENERAL_REGS,
3684b169a6bSchristos     arc_fill_gregset, arc_store_gregset
3694b169a6bSchristos   },
3704b169a6bSchristos #ifdef ARC_HAS_V2_REGSET
3714b169a6bSchristos   { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_ARC_V2,
3724b169a6bSchristos     sizeof (struct user_regs_arcv2), GENERAL_REGS,
3734b169a6bSchristos     arc_fill_v2_regset, arc_store_v2_regset
3744b169a6bSchristos   },
3754b169a6bSchristos #endif
3764b169a6bSchristos   NULL_REGSET
3774b169a6bSchristos };
3784b169a6bSchristos 
3794b169a6bSchristos static struct regsets_info arc_regsets_info =
3804b169a6bSchristos {
3814b169a6bSchristos   arc_regsets,	/* regsets */
3824b169a6bSchristos   0,		/* num_regsets */
3834b169a6bSchristos   nullptr,	/* disabled regsets */
3844b169a6bSchristos };
3854b169a6bSchristos 
3864b169a6bSchristos static struct regs_info arc_regs_info =
3874b169a6bSchristos {
3884b169a6bSchristos   nullptr,	/* regset_bitmap */
3894b169a6bSchristos   nullptr,	/* usrregs */
3904b169a6bSchristos   &arc_regsets_info
3914b169a6bSchristos };
3924b169a6bSchristos 
3934b169a6bSchristos const regs_info *
3944b169a6bSchristos arc_target::get_regs_info ()
3954b169a6bSchristos {
3964b169a6bSchristos   return &arc_regs_info;
3974b169a6bSchristos }
3984b169a6bSchristos 
3994b169a6bSchristos /* One of the methods necessary for Z0 packet support.  */
4004b169a6bSchristos 
4014b169a6bSchristos const gdb_byte *
4024b169a6bSchristos arc_target::sw_breakpoint_from_kind (int kind, int *size)
4034b169a6bSchristos {
4044b169a6bSchristos   gdb_assert (kind == TRAP_S_1_SIZE);
4054b169a6bSchristos   *size = kind;
4064b169a6bSchristos   return arc_linux_trap_s;
4074b169a6bSchristos }
4084b169a6bSchristos 
4094b169a6bSchristos /* The linux target ops object.  */
4104b169a6bSchristos 
4114b169a6bSchristos linux_process_target *the_linux_target = &the_arc_target;
4124b169a6bSchristos 
4134b169a6bSchristos void
4144b169a6bSchristos initialize_low_arch (void)
4154b169a6bSchristos {
4164b169a6bSchristos   initialize_regsets_info (&arc_regsets_info);
4174b169a6bSchristos }
418