xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/csky-linux-tdep.c (revision 6881a4007f077b54e5f51159c52b9b25f57deb0d)
17f2ac410Schristos /* Target-dependent code for GNU/Linux on CSKY.
27f2ac410Schristos 
3*6881a400Schristos    Copyright (C) 2012-2023 Free Software Foundation, Inc.
47f2ac410Schristos 
57f2ac410Schristos    Contributed by C-SKY Microsystems and Mentor Graphics.
67f2ac410Schristos 
77f2ac410Schristos    This file is part of GDB.
87f2ac410Schristos 
97f2ac410Schristos    This program is free software; you can redistribute it and/or modify
107f2ac410Schristos    it under the terms of the GNU General Public License as published by
117f2ac410Schristos    the Free Software Foundation; either version 3 of the License, or
127f2ac410Schristos    (at your option) any later version.
137f2ac410Schristos 
147f2ac410Schristos    This program is distributed in the hope that it will be useful,
157f2ac410Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
167f2ac410Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
177f2ac410Schristos    GNU General Public License for more details.
187f2ac410Schristos 
197f2ac410Schristos    You should have received a copy of the GNU General Public License
207f2ac410Schristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
217f2ac410Schristos 
227f2ac410Schristos #include "defs.h"
237f2ac410Schristos #include "osabi.h"
247f2ac410Schristos #include "glibc-tdep.h"
257f2ac410Schristos #include "linux-tdep.h"
267f2ac410Schristos #include "gdbarch.h"
277f2ac410Schristos #include "solib-svr4.h"
287f2ac410Schristos #include "regset.h"
297f2ac410Schristos #include "trad-frame.h"
307f2ac410Schristos #include "tramp-frame.h"
317f2ac410Schristos #include "csky-tdep.h"
327f2ac410Schristos 
337f2ac410Schristos /* Functions, definitions, and data structures for C-Sky core file debug.  */
347f2ac410Schristos 
357f2ac410Schristos /* General regset pc, r1, r0, psr, r2-r31 for CK810.  */
367f2ac410Schristos #define SIZEOF_CSKY_GREGSET 34*4
377f2ac410Schristos /* Float regset fesr fsr fr0-fr31 for CK810.  */
387f2ac410Schristos #define SIZEOF_CSKY_FREGSET 34*4
39*6881a400Schristos /* Float regset vr0~vr15 fr15~fr31, reserved for CK810 when kernel 4.x.  */
40*6881a400Schristos #define SIZEOF_CSKY_FREGSET_K4X  400
417f2ac410Schristos 
427f2ac410Schristos /* Offset mapping table from core_section to regcache of general
437f2ac410Schristos    registers for ck810.  */
447f2ac410Schristos static const int csky_gregset_offset[] =
457f2ac410Schristos {
467f2ac410Schristos   72,  1,  0, 89,  2,  /* pc, r1, r0, psr, r2.  */
477f2ac410Schristos    3,  4,  5,  6,  7,  /* r3 ~ r32.  */
487f2ac410Schristos    8,  9, 10, 11, 12,
497f2ac410Schristos   13, 14, 15, 16, 17,
507f2ac410Schristos   18, 19, 20, 21, 22,
517f2ac410Schristos   23, 24, 25, 26, 27,
527f2ac410Schristos   28, 29, 30, 31
537f2ac410Schristos };
547f2ac410Schristos 
557f2ac410Schristos /* Offset mapping table from core_section to regcache of float
567f2ac410Schristos    registers for ck810.  */
577f2ac410Schristos 
587f2ac410Schristos static const int csky_fregset_offset[] =
597f2ac410Schristos {
607f2ac410Schristos   122, 123, 40, 41, 42,     /* fcr, fesr, fr0 ~ fr2.  */
617f2ac410Schristos    43,  44, 45, 46, 47,     /* fr3 ~ fr15.  */
627f2ac410Schristos    48,  49, 50, 51, 52,
637f2ac410Schristos    53,  54, 55
647f2ac410Schristos };
657f2ac410Schristos 
667f2ac410Schristos /* Implement the supply_regset hook for GP registers in core files.  */
677f2ac410Schristos 
687f2ac410Schristos static void
697f2ac410Schristos csky_supply_gregset (const struct regset *regset,
707f2ac410Schristos 		     struct regcache *regcache, int regnum,
717f2ac410Schristos 		     const void *regs, size_t len)
727f2ac410Schristos {
737f2ac410Schristos   int i, gregset_num;
747f2ac410Schristos   const gdb_byte *gregs = (const gdb_byte *) regs ;
757f2ac410Schristos 
767f2ac410Schristos   gdb_assert (len >= SIZEOF_CSKY_GREGSET);
777f2ac410Schristos   gregset_num = ARRAY_SIZE (csky_gregset_offset);
787f2ac410Schristos 
797f2ac410Schristos   for (i = 0; i < gregset_num; i++)
807f2ac410Schristos     {
817f2ac410Schristos       if ((regnum == csky_gregset_offset[i] || regnum == -1)
827f2ac410Schristos 	  && csky_gregset_offset[i] != -1)
837f2ac410Schristos 	regcache->raw_supply (csky_gregset_offset[i], gregs + 4 * i);
847f2ac410Schristos     }
857f2ac410Schristos }
867f2ac410Schristos 
877f2ac410Schristos /* Implement the collect_regset hook for GP registers in core files.  */
887f2ac410Schristos 
897f2ac410Schristos static void
907f2ac410Schristos csky_collect_gregset (const struct regset *regset,
917f2ac410Schristos 		      const struct regcache *regcache,
927f2ac410Schristos 		      int regnum, void *gregs_buf, size_t len)
937f2ac410Schristos {
947f2ac410Schristos   int regno, gregset_num;
957f2ac410Schristos   gdb_byte *gregs = (gdb_byte *) gregs_buf ;
967f2ac410Schristos 
977f2ac410Schristos   gdb_assert (len >= SIZEOF_CSKY_GREGSET);
987f2ac410Schristos   gregset_num = ARRAY_SIZE (csky_gregset_offset);
997f2ac410Schristos 
1007f2ac410Schristos   for (regno = 0; regno < gregset_num; regno++)
1017f2ac410Schristos     {
1027f2ac410Schristos       if ((regnum == csky_gregset_offset[regno] || regnum == -1)
1037f2ac410Schristos 	  && csky_gregset_offset[regno] != -1)
1047f2ac410Schristos 	regcache->raw_collect (regno,
1057f2ac410Schristos 			       gregs + 4 + csky_gregset_offset[regno]);
1067f2ac410Schristos     }
1077f2ac410Schristos }
1087f2ac410Schristos 
1097f2ac410Schristos /* Implement the supply_regset hook for FP registers in core files.  */
1107f2ac410Schristos 
1117d62b00eSchristos static void
1127f2ac410Schristos csky_supply_fregset (const struct regset *regset,
1137f2ac410Schristos 		     struct regcache *regcache, int regnum,
1147f2ac410Schristos 		     const void *regs, size_t len)
1157f2ac410Schristos {
1167f2ac410Schristos   int i;
1177f2ac410Schristos   int offset = 0;
1187f2ac410Schristos   struct gdbarch *gdbarch = regcache->arch ();
1197f2ac410Schristos   const gdb_byte *fregs = (const gdb_byte *) regs;
1207f2ac410Schristos   int fregset_num = ARRAY_SIZE (csky_fregset_offset);
1217f2ac410Schristos 
1227f2ac410Schristos   gdb_assert (len >= SIZEOF_CSKY_FREGSET);
123*6881a400Schristos   if (len == SIZEOF_CSKY_FREGSET)
124*6881a400Schristos     {
1257f2ac410Schristos       for (i = 0; i < fregset_num; i++)
1267f2ac410Schristos 	{
1277f2ac410Schristos 	  if ((regnum == csky_fregset_offset[i] || regnum == -1)
1287f2ac410Schristos 	      && csky_fregset_offset[i] != -1)
1297f2ac410Schristos 	    {
1307f2ac410Schristos 	      int num = csky_fregset_offset[i];
1317f2ac410Schristos 	      offset += register_size (gdbarch, num);
1327f2ac410Schristos 	      regcache->raw_supply (csky_fregset_offset[i], fregs + offset);
1337f2ac410Schristos 	    }
1347f2ac410Schristos 	}
1357f2ac410Schristos     }
136*6881a400Schristos   else if (len == SIZEOF_CSKY_FREGSET_K4X)
137*6881a400Schristos     {
138*6881a400Schristos       /* When kernel version >= 4.x, .reg2 size will be 400.
139*6881a400Schristos 	 Contents is {
140*6881a400Schristos 	  unsigned long vr[96];
141*6881a400Schristos 	  unsigned long fcr;
142*6881a400Schristos 	  unsigned long fesr;
143*6881a400Schristos 	  unsigned long fid;
144*6881a400Schristos 	  unsigned long reserved;
145*6881a400Schristos 	 }
146*6881a400Schristos 	 VR[96] means: (vr0~vr15) + (fr16~fr31), each Vector register is
147*6881a400Schristos 	 128-bits, each Float register is 64 bits, the total size is
148*6881a400Schristos 	 (4*96).
149*6881a400Schristos 
150*6881a400Schristos 	 In addition, for fr0~fr15, each FRx is the lower 64 bits of the
151*6881a400Schristos 	 corresponding VRx. So fr0~fr15 and vr0~vr15 regisetrs use the same
152*6881a400Schristos 	 offset.  */
153*6881a400Schristos       int fcr_regno[] = {122, 123, 121}; /* fcr, fesr, fid.  */
154*6881a400Schristos 
155*6881a400Schristos       /* Supply vr0~vr15.  */
156*6881a400Schristos       for (i = 0; i < 16; i ++)
157*6881a400Schristos 	{
158*6881a400Schristos 	  if (*gdbarch_register_name (gdbarch, (CSKY_VR0_REGNUM + i)) != '\0')
159*6881a400Schristos 	    {
160*6881a400Schristos 	      offset = 16 * i;
161*6881a400Schristos 	      regcache->raw_supply (CSKY_VR0_REGNUM + i, fregs + offset);
162*6881a400Schristos 	    }
163*6881a400Schristos 	}
164*6881a400Schristos       /* Supply fr0~fr15.  */
165*6881a400Schristos       for (i = 0; i < 16; i ++)
166*6881a400Schristos 	{
167*6881a400Schristos 	  if (*gdbarch_register_name (gdbarch, (CSKY_FR0_REGNUM + i)) != '\0')
168*6881a400Schristos 	    {
169*6881a400Schristos 	      offset = 16 * i;
170*6881a400Schristos 	      regcache->raw_supply (CSKY_FR0_REGNUM + i, fregs + offset);
171*6881a400Schristos 	    }
172*6881a400Schristos 	}
173*6881a400Schristos       /* Supply fr16~fr31.  */
174*6881a400Schristos       for (i = 0; i < 16; i ++)
175*6881a400Schristos 	{
176*6881a400Schristos 	  if (*gdbarch_register_name (gdbarch, (CSKY_FR16_REGNUM + i)) != '\0')
177*6881a400Schristos 	    {
178*6881a400Schristos 	      offset = (16 * 16) + (8 * i);
179*6881a400Schristos 	      regcache->raw_supply (CSKY_FR16_REGNUM + i, fregs + offset);
180*6881a400Schristos 	    }
181*6881a400Schristos 	}
182*6881a400Schristos      /* Supply fcr, fesr, fid.  */
183*6881a400Schristos       for (i = 0; i < 3; i ++)
184*6881a400Schristos 	{
185*6881a400Schristos 	  if (*gdbarch_register_name (gdbarch, fcr_regno[i]) != '\0')
186*6881a400Schristos 	    {
187*6881a400Schristos 	      offset = (16 * 16) + (16 * 8) + (4 * i);
188*6881a400Schristos 	      regcache->raw_supply (fcr_regno[i], fregs + offset);
189*6881a400Schristos 	    }
190*6881a400Schristos 	}
191*6881a400Schristos     }
192*6881a400Schristos   else
193*6881a400Schristos     {
194*6881a400Schristos       warning (_("Unknow size %s of section .reg2, can not get value"
195*6881a400Schristos 		 " of float registers."), pulongest (len));
196*6881a400Schristos     }
197*6881a400Schristos }
1987f2ac410Schristos 
1997f2ac410Schristos /* Implement the collect_regset hook for FP registers in core files.  */
2007f2ac410Schristos 
2017f2ac410Schristos static void
2027f2ac410Schristos csky_collect_fregset (const struct regset *regset,
2037f2ac410Schristos 		      const struct regcache *regcache,
2047f2ac410Schristos 		      int regnum, void *fregs_buf, size_t len)
2057f2ac410Schristos {
2067f2ac410Schristos   int regno;
2077f2ac410Schristos   struct gdbarch *gdbarch = regcache->arch ();
2087f2ac410Schristos   gdb_byte *fregs = (gdb_byte *) fregs_buf ;
2097f2ac410Schristos   int fregset_num = ARRAY_SIZE (csky_fregset_offset);
2107f2ac410Schristos   int offset = 0;
2117f2ac410Schristos 
2127f2ac410Schristos   gdb_assert (len >= SIZEOF_CSKY_FREGSET);
213*6881a400Schristos   if (len == SIZEOF_CSKY_FREGSET)
214*6881a400Schristos     {
2157f2ac410Schristos       for (regno = 0; regno < fregset_num; regno++)
2167f2ac410Schristos 	{
2177f2ac410Schristos 	  if ((regnum == csky_fregset_offset[regno] || regnum == -1)
2187f2ac410Schristos 	       && csky_fregset_offset[regno] != -1)
2197f2ac410Schristos 	    {
2207f2ac410Schristos 	      offset += register_size (gdbarch, csky_fregset_offset[regno]);
2217f2ac410Schristos 	      regcache->raw_collect (regno, fregs + offset);
2227f2ac410Schristos 	    }
2237f2ac410Schristos 	}
2247f2ac410Schristos     }
225*6881a400Schristos   else if (len == SIZEOF_CSKY_FREGSET_K4X)
226*6881a400Schristos     {
227*6881a400Schristos       /* When kernel version >= 4.x, .reg2 size will be 400.
228*6881a400Schristos 	 Contents is {
229*6881a400Schristos 	   unsigned long vr[96];
230*6881a400Schristos 	   unsigned long fcr;
231*6881a400Schristos 	   unsigned long fesr;
232*6881a400Schristos 	   unsigned long fid;
233*6881a400Schristos 	   unsigned long reserved;
234*6881a400Schristos 	 }
235*6881a400Schristos 	 VR[96] means: (vr0~vr15) + (fr16~fr31), each Vector register is$
236*6881a400Schristos 	 128-bits, each Float register is 64 bits, the total size is$
237*6881a400Schristos 	 (4*96).$
238*6881a400Schristos 
239*6881a400Schristos 	 In addition, for fr0~fr15, each FRx is the lower 64 bits of the$
240*6881a400Schristos 	 corresponding VRx. So fr0~fr15 and vr0~vr15 regisetrs use the same$
241*6881a400Schristos 	 offset.  */
242*6881a400Schristos       int i = 0;
243*6881a400Schristos       int fcr_regno[] = {122, 123, 121}; /* fcr, fesr, fid.  */
244*6881a400Schristos 
245*6881a400Schristos       /* Supply vr0~vr15.  */
246*6881a400Schristos       for (i = 0; i < 16; i ++)
247*6881a400Schristos 	{
248*6881a400Schristos 	  if (*gdbarch_register_name (gdbarch, (CSKY_VR0_REGNUM + i)) != '\0')
249*6881a400Schristos 	    {
250*6881a400Schristos 	      offset = 16 * i;
251*6881a400Schristos 	      regcache ->raw_collect (CSKY_VR0_REGNUM + i, fregs + offset);
252*6881a400Schristos 	    }
253*6881a400Schristos 	}
254*6881a400Schristos       /* Supply fr16~fr31.  */
255*6881a400Schristos       for (i = 0; i < 16; i ++)
256*6881a400Schristos 	{
257*6881a400Schristos 	  if (*gdbarch_register_name (gdbarch, (CSKY_FR16_REGNUM + i)) != '\0')
258*6881a400Schristos 	    {
259*6881a400Schristos 	      offset = (16 * 16) + (8 * i);
260*6881a400Schristos 	      regcache ->raw_collect (CSKY_FR16_REGNUM + i, fregs + offset);
261*6881a400Schristos 	    }
262*6881a400Schristos 	}
263*6881a400Schristos       /* Supply fcr, fesr, fid.  */
264*6881a400Schristos       for (i = 0; i < 3; i ++)
265*6881a400Schristos 	{
266*6881a400Schristos 	  if (*gdbarch_register_name (gdbarch, fcr_regno[i]) != '\0')
267*6881a400Schristos 	    {
268*6881a400Schristos 	      offset = (16 * 16) + (16 * 8) + (4 * i);
269*6881a400Schristos 	      regcache ->raw_collect (fcr_regno[i], fregs + offset);
270*6881a400Schristos 	    }
271*6881a400Schristos 	}
272*6881a400Schristos     }
273*6881a400Schristos   else
274*6881a400Schristos     {
275*6881a400Schristos       warning (_("Unknow size %s of section .reg2, will not set value"
276*6881a400Schristos 		 " of float registers."), pulongest (len));
277*6881a400Schristos     }
278*6881a400Schristos }
2797f2ac410Schristos 
2807f2ac410Schristos static const struct regset csky_regset_general =
2817f2ac410Schristos {
2827f2ac410Schristos   NULL,
2837f2ac410Schristos   csky_supply_gregset,
2847f2ac410Schristos   csky_collect_gregset
2857f2ac410Schristos };
2867f2ac410Schristos 
2877f2ac410Schristos static const struct regset csky_regset_float =
2887f2ac410Schristos {
2897f2ac410Schristos   NULL,
2907f2ac410Schristos   csky_supply_fregset,
291*6881a400Schristos   csky_collect_fregset,
292*6881a400Schristos   /* Allow .reg2 to have a different size, and the size of .reg2 should
293*6881a400Schristos      always be bigger than SIZEOF_CSKY_FREGSET.  */
294*6881a400Schristos   1
2957f2ac410Schristos };
2967f2ac410Schristos 
2977f2ac410Schristos /* Iterate over core file register note sections.  */
2987f2ac410Schristos 
2997f2ac410Schristos static void
3007f2ac410Schristos csky_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
3017f2ac410Schristos 					 iterate_over_regset_sections_cb *cb,
3027f2ac410Schristos 					 void *cb_data,
3037f2ac410Schristos 					 const struct regcache *regcache)
3047f2ac410Schristos {
3057f2ac410Schristos   cb (".reg", sizeof (csky_gregset_offset), sizeof (csky_gregset_offset),
3067f2ac410Schristos       &csky_regset_general, NULL, cb_data);
3077f2ac410Schristos   cb (".reg2", sizeof (csky_fregset_offset), sizeof (csky_fregset_offset),
3087f2ac410Schristos       &csky_regset_float, NULL, cb_data);
3097f2ac410Schristos }
3107f2ac410Schristos 
3117f2ac410Schristos static void
3127f2ac410Schristos csky_linux_rt_sigreturn_init (const struct tramp_frame *self,
313*6881a400Schristos 			      frame_info_ptr this_frame,
3147f2ac410Schristos 			      struct trad_frame_cache *this_cache,
3157f2ac410Schristos 			      CORE_ADDR func)
3167f2ac410Schristos {
3177f2ac410Schristos   int i;
3187f2ac410Schristos   CORE_ADDR sp = get_frame_register_unsigned (this_frame, 14);
3197f2ac410Schristos 
3207f2ac410Schristos   CORE_ADDR base = sp + CSKY_SIGINFO_OFFSET + CSKY_SIGINFO_SIZE
3217f2ac410Schristos 		   + CSKY_UCONTEXT_SIGCONTEXT
3227f2ac410Schristos 		   + CSKY_SIGCONTEXT_SC_USP
3237f2ac410Schristos 		   + CSKY_SIGCONTEXT_SC_A0;
3247f2ac410Schristos 
3257f2ac410Schristos   /* Set addrs of R0 ~ R13.  */
3267f2ac410Schristos   for (i = 0; i < 14; i++)
3277f2ac410Schristos    trad_frame_set_reg_addr (this_cache, i, base + i * 4);
3287f2ac410Schristos 
3297f2ac410Schristos   /* Set addrs of SP(R14) and R15.  */
3307f2ac410Schristos   trad_frame_set_reg_addr (this_cache, 14, base - 4);
3317f2ac410Schristos   trad_frame_set_reg_addr (this_cache, 15, base + 4 * 14);
3327f2ac410Schristos 
3337f2ac410Schristos   /* Set addrs of R16 ~ R31.  */
3347f2ac410Schristos   for (i = 15; i < 31; i++)
3357f2ac410Schristos    trad_frame_set_reg_addr (this_cache, i, base + i * 4);
3367f2ac410Schristos 
3377f2ac410Schristos   /* Set addrs of PSR and PC.  */
3387f2ac410Schristos   trad_frame_set_reg_addr (this_cache, 89, base + 4 * 33);
3397f2ac410Schristos   trad_frame_set_reg_addr (this_cache, 72, base + 4 * 34);
3407f2ac410Schristos 
3417f2ac410Schristos   trad_frame_set_id (this_cache, frame_id_build (sp, func));
3427f2ac410Schristos }
3437f2ac410Schristos 
3447f2ac410Schristos static struct tramp_frame
3457f2ac410Schristos csky_linux_rt_sigreturn_tramp_frame = {
3467f2ac410Schristos   SIGTRAMP_FRAME,
3477f2ac410Schristos   4,
3487f2ac410Schristos   {
3497f2ac410Schristos     { CSKY_MOVI_R7_173, ULONGEST_MAX },
3507f2ac410Schristos     { CSKY_TRAP_0, ULONGEST_MAX },
3517f2ac410Schristos     { TRAMP_SENTINEL_INSN }
3527f2ac410Schristos   },
3537f2ac410Schristos   csky_linux_rt_sigreturn_init
3547f2ac410Schristos };
3557f2ac410Schristos 
356*6881a400Schristos static void
357*6881a400Schristos csky_linux_rt_sigreturn_init_pt_regs (const struct tramp_frame *self,
358*6881a400Schristos 				      frame_info_ptr this_frame,
359*6881a400Schristos 				      struct trad_frame_cache *this_cache,
360*6881a400Schristos 				      CORE_ADDR func)
361*6881a400Schristos {
362*6881a400Schristos   int i;
363*6881a400Schristos   CORE_ADDR sp = get_frame_register_unsigned (this_frame, CSKY_SP_REGNUM);
364*6881a400Schristos 
365*6881a400Schristos   CORE_ADDR base = sp + CSKY_SIGINFO_OFFSET + CSKY_SIGINFO_SIZE
366*6881a400Schristos 		   + CSKY_UCONTEXT_SIGCONTEXT
367*6881a400Schristos 		   + CSKY_SIGCONTEXT_PT_REGS_TLS;
368*6881a400Schristos 
369*6881a400Schristos   /* LR */
370*6881a400Schristos   trad_frame_set_reg_addr (this_cache, CSKY_R15_REGNUM, base);
371*6881a400Schristos 
372*6881a400Schristos   /* PC */
373*6881a400Schristos   trad_frame_set_reg_addr (this_cache, CSKY_PC_REGNUM, base + 4);
374*6881a400Schristos 
375*6881a400Schristos   /* PSR */
376*6881a400Schristos   trad_frame_set_reg_addr (this_cache, CSKY_CR0_REGNUM, base + 8);
377*6881a400Schristos 
378*6881a400Schristos   /* SP */
379*6881a400Schristos   trad_frame_set_reg_addr (this_cache, CSKY_SP_REGNUM, base + 12);
380*6881a400Schristos 
381*6881a400Schristos   /* Set addrs of R0 ~ R13.  */
382*6881a400Schristos   for (i = 0; i < 14; i++)
383*6881a400Schristos     trad_frame_set_reg_addr (this_cache, i, base + i * 4 + 20);
384*6881a400Schristos 
385*6881a400Schristos   trad_frame_set_id (this_cache, frame_id_build (sp, func));
386*6881a400Schristos }
387*6881a400Schristos 
388*6881a400Schristos 
389*6881a400Schristos static struct tramp_frame
390*6881a400Schristos csky_linux_rt_sigreturn_tramp_frame_kernel_4x = {
391*6881a400Schristos   SIGTRAMP_FRAME,
392*6881a400Schristos   4,
393*6881a400Schristos   {
394*6881a400Schristos     { CSKY_MOVI_R7_139, ULONGEST_MAX },
395*6881a400Schristos     { CSKY_TRAP_0, ULONGEST_MAX },
396*6881a400Schristos     { TRAMP_SENTINEL_INSN }
397*6881a400Schristos   },
398*6881a400Schristos   csky_linux_rt_sigreturn_init_pt_regs
399*6881a400Schristos };
400*6881a400Schristos 
4017f2ac410Schristos /* Hook function for gdbarch_register_osabi.  */
4027f2ac410Schristos 
4037f2ac410Schristos static void
4047f2ac410Schristos csky_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
4057f2ac410Schristos {
406*6881a400Schristos   linux_init_abi (info, gdbarch, 0);
4077f2ac410Schristos 
4087f2ac410Schristos   /* Shared library handling.  */
4097f2ac410Schristos   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
4107f2ac410Schristos   set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
4117f2ac410Schristos   set_solib_svr4_fetch_link_map_offsets (gdbarch,
412*6881a400Schristos 					 linux_ilp32_fetch_link_map_offsets);
4137f2ac410Schristos 
4147f2ac410Schristos   /* Enable TLS support.  */
4157f2ac410Schristos   set_gdbarch_fetch_tls_load_module_address (gdbarch,
4167f2ac410Schristos 					     svr4_fetch_objfile_link_map);
4177f2ac410Schristos 
4187f2ac410Schristos   /* Core file support.  */
4197f2ac410Schristos   set_gdbarch_iterate_over_regset_sections (
4207f2ac410Schristos     gdbarch, csky_linux_iterate_over_regset_sections);
4217f2ac410Schristos 
4227f2ac410Schristos   /* Append tramp frame unwinder for SIGNAL.  */
4237f2ac410Schristos 
4247f2ac410Schristos   tramp_frame_prepend_unwinder (gdbarch,
4257f2ac410Schristos 				&csky_linux_rt_sigreturn_tramp_frame);
426*6881a400Schristos   tramp_frame_prepend_unwinder (gdbarch,
427*6881a400Schristos 				&csky_linux_rt_sigreturn_tramp_frame_kernel_4x);
4287f2ac410Schristos }
4297f2ac410Schristos 
4307d62b00eSchristos void _initialize_csky_linux_tdep ();
4317f2ac410Schristos void
4327d62b00eSchristos _initialize_csky_linux_tdep ()
4337f2ac410Schristos {
4347f2ac410Schristos   gdbarch_register_osabi (bfd_arch_csky, 0, GDB_OSABI_LINUX,
4357f2ac410Schristos 			  csky_linux_init_abi);
4367f2ac410Schristos }
437