Add translations for various sub-directories
[binutils-gdb.git] / gdb / loongarch-linux-tdep.c
blobb18cacca087d96b5af8ffd0c3b244fa270c6d49c
1 /* Target-dependent code for GNU/Linux on LoongArch processors.
3 Copyright (C) 2022-2024 Free Software Foundation, Inc.
4 Contributed by Loongson Ltd.
6 This file is part of GDB.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 #include "arch/loongarch-syscall.h"
22 #include "extract-store-integer.h"
23 #include "gdbarch.h"
24 #include "glibc-tdep.h"
25 #include "inferior.h"
26 #include "linux-record.h"
27 #include "linux-tdep.h"
28 #include "loongarch-tdep.h"
29 #include "record-full.h"
30 #include "regset.h"
31 #include "solib-svr4.h"
32 #include "target-descriptions.h"
33 #include "trad-frame.h"
34 #include "tramp-frame.h"
35 #include "value.h"
36 #include "xml-syscall.h"
38 /* The syscall's XML filename for LoongArch. */
39 #define XML_SYSCALL_FILENAME_LOONGARCH "syscalls/loongarch-linux.xml"
41 /* Unpack an elf_gregset_t into GDB's register cache. */
43 static void
44 loongarch_supply_gregset (const struct regset *regset,
45 struct regcache *regcache, int regnum,
46 const void *gprs, size_t len)
48 int regsize = register_size (regcache->arch (), 0);
49 const gdb_byte *buf = nullptr;
51 if (regnum == -1)
53 regcache->raw_supply_zeroed (0);
55 for (int i = 1; i < 32; i++)
57 buf = (const gdb_byte*) gprs + regsize * i;
58 regcache->raw_supply (i, (const void *) buf);
61 buf = (const gdb_byte*) gprs + regsize * LOONGARCH_ORIG_A0_REGNUM;
62 regcache->raw_supply (LOONGARCH_ORIG_A0_REGNUM, (const void *) buf);
64 buf = (const gdb_byte*) gprs + regsize * LOONGARCH_PC_REGNUM;
65 regcache->raw_supply (LOONGARCH_PC_REGNUM, (const void *) buf);
67 buf = (const gdb_byte*) gprs + regsize * LOONGARCH_BADV_REGNUM;
68 regcache->raw_supply (LOONGARCH_BADV_REGNUM, (const void *) buf);
70 else if (regnum == 0)
71 regcache->raw_supply_zeroed (0);
72 else if ((regnum > 0 && regnum < 32)
73 || regnum == LOONGARCH_ORIG_A0_REGNUM
74 || regnum == LOONGARCH_PC_REGNUM
75 || regnum == LOONGARCH_BADV_REGNUM)
77 buf = (const gdb_byte*) gprs + regsize * regnum;
78 regcache->raw_supply (regnum, (const void *) buf);
82 /* Pack the GDB's register cache value into an elf_gregset_t. */
84 static void
85 loongarch_fill_gregset (const struct regset *regset,
86 const struct regcache *regcache, int regnum,
87 void *gprs, size_t len)
89 int regsize = register_size (regcache->arch (), 0);
90 gdb_byte *buf = nullptr;
92 if (regnum == -1)
94 for (int i = 0; i < 32; i++)
96 buf = (gdb_byte *) gprs + regsize * i;
97 regcache->raw_collect (i, (void *) buf);
100 buf = (gdb_byte *) gprs + regsize * LOONGARCH_ORIG_A0_REGNUM;
101 regcache->raw_collect (LOONGARCH_ORIG_A0_REGNUM, (void *) buf);
103 buf = (gdb_byte *) gprs + regsize * LOONGARCH_PC_REGNUM;
104 regcache->raw_collect (LOONGARCH_PC_REGNUM, (void *) buf);
106 buf = (gdb_byte *) gprs + regsize * LOONGARCH_BADV_REGNUM;
107 regcache->raw_collect (LOONGARCH_BADV_REGNUM, (void *) buf);
109 else if ((regnum >= 0 && regnum < 32)
110 || regnum == LOONGARCH_ORIG_A0_REGNUM
111 || regnum == LOONGARCH_PC_REGNUM
112 || regnum == LOONGARCH_BADV_REGNUM)
114 buf = (gdb_byte *) gprs + regsize * regnum;
115 regcache->raw_collect (regnum, (void *) buf);
119 /* Define the general register regset. */
121 const struct regset loongarch_gregset =
123 nullptr,
124 loongarch_supply_gregset,
125 loongarch_fill_gregset,
128 /* Unpack an elf_fpregset_t into GDB's register cache. */
129 static void
130 loongarch_supply_fpregset (const struct regset *r,
131 struct regcache *regcache, int regnum,
132 const void *fprs, size_t len)
134 const gdb_byte *buf = nullptr;
135 int fprsize = register_size (regcache->arch (), LOONGARCH_FIRST_FP_REGNUM);
136 int fccsize = register_size (regcache->arch (), LOONGARCH_FIRST_FCC_REGNUM);
138 if (regnum == -1)
140 for (int i = 0; i < LOONGARCH_LINUX_NUM_FPREGSET; i++)
142 buf = (const gdb_byte *)fprs + fprsize * i;
143 regcache->raw_supply (LOONGARCH_FIRST_FP_REGNUM + i, (const void *)buf);
145 for (int i = 0; i < LOONGARCH_LINUX_NUM_FCC; i++)
147 buf = (const gdb_byte *)fprs + fprsize * LOONGARCH_LINUX_NUM_FPREGSET +
148 fccsize * i;
149 regcache->raw_supply (LOONGARCH_FIRST_FCC_REGNUM + i, (const void *)buf);
151 buf = (const gdb_byte *)fprs + fprsize * LOONGARCH_LINUX_NUM_FPREGSET +
152 fccsize * LOONGARCH_LINUX_NUM_FCC;
153 regcache->raw_supply (LOONGARCH_FCSR_REGNUM, (const void *)buf);
155 else if (regnum >= LOONGARCH_FIRST_FP_REGNUM && regnum < LOONGARCH_FIRST_FCC_REGNUM)
157 buf = (const gdb_byte *)fprs + fprsize * (regnum - LOONGARCH_FIRST_FP_REGNUM);
158 regcache->raw_supply (regnum, (const void *)buf);
160 else if (regnum >= LOONGARCH_FIRST_FCC_REGNUM && regnum < LOONGARCH_FCSR_REGNUM)
162 buf = (const gdb_byte *)fprs + fprsize * LOONGARCH_LINUX_NUM_FPREGSET +
163 fccsize * (regnum - LOONGARCH_FIRST_FCC_REGNUM);
164 regcache->raw_supply (regnum, (const void *)buf);
166 else if (regnum == LOONGARCH_FCSR_REGNUM)
168 buf = (const gdb_byte *)fprs + fprsize * LOONGARCH_LINUX_NUM_FPREGSET +
169 fccsize * LOONGARCH_LINUX_NUM_FCC;
170 regcache->raw_supply (regnum, (const void *)buf);
174 /* Pack the GDB's register cache value into an elf_fpregset_t. */
175 static void
176 loongarch_fill_fpregset (const struct regset *r,
177 const struct regcache *regcache, int regnum,
178 void *fprs, size_t len)
180 gdb_byte *buf = nullptr;
181 int fprsize = register_size (regcache->arch (), LOONGARCH_FIRST_FP_REGNUM);
182 int fccsize = register_size (regcache->arch (), LOONGARCH_FIRST_FCC_REGNUM);
184 if (regnum == -1)
186 for (int i = 0; i < LOONGARCH_LINUX_NUM_FPREGSET; i++)
188 buf = (gdb_byte *)fprs + fprsize * i;
189 regcache->raw_collect (LOONGARCH_FIRST_FP_REGNUM + i, (void *)buf);
191 for (int i = 0; i < LOONGARCH_LINUX_NUM_FCC; i++)
193 buf = (gdb_byte *)fprs + fprsize * LOONGARCH_LINUX_NUM_FPREGSET +
194 fccsize * i;
195 regcache->raw_collect (LOONGARCH_FIRST_FCC_REGNUM + i, (void *)buf);
197 buf = (gdb_byte *)fprs + fprsize * LOONGARCH_LINUX_NUM_FPREGSET +
198 fccsize * LOONGARCH_LINUX_NUM_FCC;
199 regcache->raw_collect (LOONGARCH_FCSR_REGNUM, (void *)buf);
201 else if (regnum >= LOONGARCH_FIRST_FP_REGNUM && regnum < LOONGARCH_FIRST_FCC_REGNUM)
203 buf = (gdb_byte *)fprs + fprsize * (regnum - LOONGARCH_FIRST_FP_REGNUM);
204 regcache->raw_collect (regnum, (void *)buf);
206 else if (regnum >= LOONGARCH_FIRST_FCC_REGNUM && regnum < LOONGARCH_FCSR_REGNUM)
208 buf = (gdb_byte *)fprs + fprsize * LOONGARCH_LINUX_NUM_FPREGSET +
209 fccsize * (regnum - LOONGARCH_FIRST_FCC_REGNUM);
210 regcache->raw_collect (regnum, (void *)buf);
212 else if (regnum == LOONGARCH_FCSR_REGNUM)
214 buf = (gdb_byte *)fprs + fprsize * LOONGARCH_LINUX_NUM_FPREGSET +
215 fccsize * LOONGARCH_LINUX_NUM_FCC;
216 regcache->raw_collect (regnum, (void *)buf);
220 /* Define the FP register regset. */
221 const struct regset loongarch_fpregset =
223 nullptr,
224 loongarch_supply_fpregset,
225 loongarch_fill_fpregset,
228 /* Unpack elf_lsxregset_t into GDB's register cache. */
230 static void
231 loongarch_supply_lsxregset (const struct regset *regset,
232 struct regcache *regcache, int regnum,
233 const void *lsxrs, size_t len)
235 int lsxrsize = register_size (regcache->arch (), LOONGARCH_FIRST_LSX_REGNUM);
236 const gdb_byte *buf = nullptr;
238 if (regnum == -1)
240 for (int i = 0; i < LOONGARCH_LINUX_NUM_LSXREGSET; i++)
242 buf = (const gdb_byte*) lsxrs + lsxrsize * i;
243 regcache->raw_supply (LOONGARCH_FIRST_LSX_REGNUM + i, (const void *) buf);
247 else if (regnum >= LOONGARCH_FIRST_LSX_REGNUM && regnum < LOONGARCH_FIRST_LASX_REGNUM)
249 buf = (const gdb_byte*) lsxrs + lsxrsize * (regnum - LOONGARCH_FIRST_LSX_REGNUM);
250 regcache->raw_supply (regnum, (const void *) buf);
254 /* Pack the GDB's register cache value into an elf_lsxregset_t. */
256 static void
257 loongarch_fill_lsxregset (const struct regset *regset,
258 const struct regcache *regcache, int regnum,
259 void *lsxrs, size_t len)
261 int lsxrsize = register_size (regcache->arch (), LOONGARCH_FIRST_LSX_REGNUM);
262 gdb_byte *buf = nullptr;
264 if (regnum == -1)
266 for (int i = 0; i < LOONGARCH_LINUX_NUM_LSXREGSET; i++)
268 buf = (gdb_byte *) lsxrs + lsxrsize * i;
269 regcache->raw_collect (LOONGARCH_FIRST_LSX_REGNUM + i, (void *) buf);
272 else if (regnum >= LOONGARCH_FIRST_LSX_REGNUM && regnum < LOONGARCH_FIRST_LASX_REGNUM)
274 buf = (gdb_byte *) lsxrs + lsxrsize * (regnum - LOONGARCH_FIRST_LSX_REGNUM);
275 regcache->raw_collect (regnum, (void *) buf);
279 /* Define the Loongson SIMD Extension register regset. */
281 const struct regset loongarch_lsxregset =
283 nullptr,
284 loongarch_supply_lsxregset,
285 loongarch_fill_lsxregset,
288 /* Unpack elf_lasxregset_t into GDB's register cache. */
290 static void
291 loongarch_supply_lasxregset (const struct regset *regset,
292 struct regcache *regcache, int regnum,
293 const void *lasxrs, size_t len)
295 int lasxrsize = register_size (regcache->arch (), LOONGARCH_FIRST_LASX_REGNUM);
296 const gdb_byte *buf = nullptr;
298 if (regnum == -1)
300 for (int i = 0; i < LOONGARCH_LINUX_NUM_LASXREGSET; i++)
302 buf = (const gdb_byte*) lasxrs + lasxrsize * i;
303 regcache->raw_supply (LOONGARCH_FIRST_LASX_REGNUM + i, (const void *) buf);
307 else if (regnum >= LOONGARCH_FIRST_LASX_REGNUM
308 && regnum < LOONGARCH_FIRST_LASX_REGNUM + LOONGARCH_LINUX_NUM_LASXREGSET)
310 buf = (const gdb_byte*) lasxrs + lasxrsize * (regnum - LOONGARCH_FIRST_LASX_REGNUM);
311 regcache->raw_supply (regnum, (const void *) buf);
315 /* Pack the GDB's register cache value into an elf_lasxregset_t. */
317 static void
318 loongarch_fill_lasxregset (const struct regset *regset,
319 const struct regcache *regcache, int regnum,
320 void *lasxrs, size_t len)
322 int lasxrsize = register_size (regcache->arch (), LOONGARCH_FIRST_LASX_REGNUM);
323 gdb_byte *buf = nullptr;
325 if (regnum == -1)
327 for (int i = 0; i < LOONGARCH_LINUX_NUM_LASXREGSET; i++)
329 buf = (gdb_byte *) lasxrs + lasxrsize * i;
330 regcache->raw_collect (LOONGARCH_FIRST_LASX_REGNUM + i, (void *) buf);
333 else if (regnum >= LOONGARCH_FIRST_LASX_REGNUM
334 && regnum < LOONGARCH_FIRST_LASX_REGNUM + LOONGARCH_LINUX_NUM_LASXREGSET)
337 buf = (gdb_byte *) lasxrs + lasxrsize * (regnum - LOONGARCH_FIRST_LASX_REGNUM);
338 regcache->raw_collect (regnum, (void *) buf);
342 /* Define the Loongson Advanced SIMD Extension register regset. */
344 const struct regset loongarch_lasxregset =
346 nullptr,
347 loongarch_supply_lasxregset,
348 loongarch_fill_lasxregset,
351 /* Unpack an lbt regset into GDB's register cache. */
353 static void
354 loongarch_supply_lbtregset (const struct regset *regset,
355 struct regcache *regcache, int regnum,
356 const void *regs, size_t len)
358 int scrsize = register_size (regcache->arch (), LOONGARCH_FIRST_SCR_REGNUM);
359 int eflagssize = register_size (regcache->arch (), LOONGARCH_EFLAGS_REGNUM);
360 const gdb_byte *buf = nullptr;
362 if (regnum == -1)
364 for (int i = 0; i < LOONGARCH_LINUX_NUM_SCR; i++)
366 buf = (const gdb_byte *) regs + scrsize * i;
367 regcache->raw_supply (LOONGARCH_FIRST_SCR_REGNUM + i,
368 (const void *) buf);
371 buf = (const gdb_byte*) regs + scrsize * LOONGARCH_LINUX_NUM_SCR;
372 regcache->raw_supply (LOONGARCH_EFLAGS_REGNUM, (const void *) buf);
374 buf = (const gdb_byte*) regs
375 + scrsize * LOONGARCH_LINUX_NUM_SCR
376 + eflagssize;
377 regcache->raw_supply (LOONGARCH_FTOP_REGNUM, (const void *) buf);
379 else if (regnum >= LOONGARCH_FIRST_SCR_REGNUM
380 && regnum <= LOONGARCH_LAST_SCR_REGNUM)
382 buf = (const gdb_byte*) regs
383 + scrsize * (regnum - LOONGARCH_FIRST_SCR_REGNUM);
384 regcache->raw_supply (regnum, (const void *) buf);
386 else if (regnum == LOONGARCH_EFLAGS_REGNUM)
388 buf = (const gdb_byte*) regs + scrsize * LOONGARCH_LINUX_NUM_SCR;
389 regcache->raw_supply (regnum, (const void *) buf);
391 else if (regnum == LOONGARCH_FTOP_REGNUM)
393 buf = (const gdb_byte*) regs
394 + scrsize * LOONGARCH_LINUX_NUM_SCR
395 + eflagssize;
396 regcache->raw_supply (regnum, (const void *) buf);
400 /* Pack the GDB's register cache value into an lbt regset. */
402 static void
403 loongarch_fill_lbtregset (const struct regset *regset,
404 const struct regcache *regcache, int regnum,
405 void *regs, size_t len)
407 int scrsize = register_size (regcache->arch (), LOONGARCH_FIRST_SCR_REGNUM);
408 int eflagssize = register_size (regcache->arch (), LOONGARCH_EFLAGS_REGNUM);
409 gdb_byte *buf = nullptr;
411 if (regnum == -1)
413 for (int i = 0; i < LOONGARCH_LINUX_NUM_SCR; i++)
415 buf = (gdb_byte *) regs + scrsize * i;
416 regcache->raw_collect (LOONGARCH_FIRST_SCR_REGNUM + i, (void *) buf);
419 buf = (gdb_byte *) regs + scrsize * LOONGARCH_LINUX_NUM_SCR;
420 regcache->raw_collect (LOONGARCH_EFLAGS_REGNUM, (void *) buf);
422 buf = (gdb_byte *) regs + scrsize * LOONGARCH_LINUX_NUM_SCR + eflagssize;
423 regcache->raw_collect (LOONGARCH_FTOP_REGNUM, (void *) buf);
425 else if (regnum >= LOONGARCH_FIRST_SCR_REGNUM
426 && regnum <= LOONGARCH_LAST_SCR_REGNUM)
428 buf = (gdb_byte *) regs + scrsize * (regnum - LOONGARCH_FIRST_SCR_REGNUM);
429 regcache->raw_collect (regnum, (void *) buf);
431 else if (regnum == LOONGARCH_EFLAGS_REGNUM)
433 buf = (gdb_byte *) regs + scrsize * LOONGARCH_LINUX_NUM_SCR;
434 regcache->raw_collect (regnum, (void *) buf);
436 else if (regnum == LOONGARCH_FTOP_REGNUM)
438 buf = (gdb_byte *) regs + scrsize * LOONGARCH_LINUX_NUM_SCR + eflagssize;
439 regcache->raw_collect (regnum, (void *) buf);
443 /* Define the lbt register regset. */
445 const struct regset loongarch_lbtregset =
447 nullptr,
448 loongarch_supply_lbtregset,
449 loongarch_fill_lbtregset,
452 /* Implement the "init" method of struct tramp_frame. */
454 #define LOONGARCH_RT_SIGFRAME_UCONTEXT_OFFSET 128
455 #define LOONGARCH_UCONTEXT_SIGCONTEXT_OFFSET 176
457 static void
458 loongarch_linux_rt_sigframe_init (const struct tramp_frame *self,
459 const frame_info_ptr &this_frame,
460 struct trad_frame_cache *this_cache,
461 CORE_ADDR func)
463 CORE_ADDR frame_sp = get_frame_sp (this_frame);
464 CORE_ADDR sigcontext_base = (frame_sp + LOONGARCH_RT_SIGFRAME_UCONTEXT_OFFSET
465 + LOONGARCH_UCONTEXT_SIGCONTEXT_OFFSET);
467 trad_frame_set_reg_addr (this_cache, LOONGARCH_PC_REGNUM, sigcontext_base);
468 for (int i = 0; i < 32; i++)
469 trad_frame_set_reg_addr (this_cache, i, sigcontext_base + 8 + i * 8);
471 trad_frame_set_id (this_cache, frame_id_build (frame_sp, func));
474 /* li.w a7, __NR_rt_sigreturn */
475 #define LOONGARCH_INST_LIW_A7_RT_SIGRETURN 0x03822c0b
476 /* syscall 0 */
477 #define LOONGARCH_INST_SYSCALL 0x002b0000
479 static const struct tramp_frame loongarch_linux_rt_sigframe =
481 SIGTRAMP_FRAME,
484 { LOONGARCH_INST_LIW_A7_RT_SIGRETURN, ULONGEST_MAX },
485 { LOONGARCH_INST_SYSCALL, ULONGEST_MAX },
486 { TRAMP_SENTINEL_INSN, ULONGEST_MAX }
488 loongarch_linux_rt_sigframe_init,
489 nullptr
492 /* Implement the "iterate_over_regset_sections" gdbarch method. */
494 static void
495 loongarch_iterate_over_regset_sections (struct gdbarch *gdbarch,
496 iterate_over_regset_sections_cb *cb,
497 void *cb_data,
498 const struct regcache *regcache)
500 int gprsize = register_size (gdbarch, 0);
501 int gpsize = gprsize * LOONGARCH_LINUX_NUM_GREGSET;
502 int fprsize = register_size (gdbarch, LOONGARCH_FIRST_FP_REGNUM);
503 int fccsize = register_size (gdbarch, LOONGARCH_FIRST_FCC_REGNUM);
504 int fcsrsize = register_size (gdbarch, LOONGARCH_FCSR_REGNUM);
505 int fpsize = fprsize * LOONGARCH_LINUX_NUM_FPREGSET +
506 fccsize * LOONGARCH_LINUX_NUM_FCC + fcsrsize;
507 int lsxrsize = register_size (gdbarch, LOONGARCH_FIRST_LSX_REGNUM);
508 int lsxsize = lsxrsize * LOONGARCH_LINUX_NUM_LSXREGSET;
509 int lasxrsize = register_size (gdbarch, LOONGARCH_FIRST_LASX_REGNUM);
510 int lasxsize = lasxrsize * LOONGARCH_LINUX_NUM_LASXREGSET;
511 int scrsize = register_size (gdbarch, LOONGARCH_FIRST_SCR_REGNUM);
512 int eflagssize = register_size (gdbarch, LOONGARCH_EFLAGS_REGNUM);
513 int ftopsize = register_size (gdbarch, LOONGARCH_FTOP_REGNUM);
514 int lbtsize = scrsize * LOONGARCH_LINUX_NUM_SCR + eflagssize + ftopsize;
516 cb (".reg", gpsize, gpsize,
517 &loongarch_gregset, nullptr, cb_data);
518 cb (".reg2", fpsize, fpsize,
519 &loongarch_fpregset, nullptr, cb_data);
520 cb (".reg-loongarch-lsx", lsxsize, lsxsize,
521 &loongarch_lsxregset, nullptr, cb_data);
522 cb (".reg-loongarch-lasx", lasxsize, lasxsize,
523 &loongarch_lasxregset, nullptr, cb_data);
524 cb (".reg-loongarch-lbt", lbtsize, lbtsize,
525 &loongarch_lbtregset, nullptr, cb_data);
528 /* The following value is derived from __NR_rt_sigreturn in
529 <include/uapi/asm-generic/unistd.h> from the Linux source tree. */
531 #define LOONGARCH_NR_rt_sigreturn 139
533 /* When FRAME is at a syscall instruction, return the PC of the next
534 instruction to be executed. */
536 static CORE_ADDR
537 loongarch_linux_syscall_next_pc (const frame_info_ptr &frame)
539 const CORE_ADDR pc = get_frame_pc (frame);
540 ULONGEST a7 = get_frame_register_unsigned (frame, LOONGARCH_A7_REGNUM);
542 /* If we are about to make a sigreturn syscall, use the unwinder to
543 decode the signal frame. */
544 if (a7 == LOONGARCH_NR_rt_sigreturn)
545 return frame_unwind_caller_pc (frame);
547 return pc + 4;
550 /* Implement the "get_syscall_number" gdbarch method. */
552 static LONGEST
553 loongarch_linux_get_syscall_number (struct gdbarch *gdbarch, thread_info *thread)
555 struct regcache *regcache = get_thread_regcache (thread);
556 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
557 int regsize = register_size (gdbarch, LOONGARCH_A7_REGNUM);
558 /* The content of a register. */
559 gdb_byte buf[8];
560 /* The result. */
561 LONGEST ret;
563 gdb_assert (regsize <= sizeof (buf));
565 /* Getting the system call number from the register.
566 When dealing with the LoongArch architecture, this information
567 is stored at the a7 register. */
568 regcache->cooked_read (LOONGARCH_A7_REGNUM, buf);
570 ret = extract_signed_integer (buf, regsize, byte_order);
572 return ret;
575 static linux_record_tdep loongarch_linux_record_tdep;
577 /* loongarch_canonicalize_syscall maps syscall ids from the native LoongArch
578 linux set of syscall ids into a canonical set of syscall ids used by
579 process record. */
581 static enum gdb_syscall
582 loongarch_canonicalize_syscall (enum loongarch_syscall syscall_number)
584 #define SYSCALL_MAP(SYSCALL) case loongarch_sys_##SYSCALL: \
585 return gdb_sys_##SYSCALL
587 #define UNSUPPORTED_SYSCALL_MAP(SYSCALL) case loongarch_sys_##SYSCALL: \
588 return gdb_sys_no_syscall
590 switch(syscall_number)
592 SYSCALL_MAP (io_setup);
593 SYSCALL_MAP (io_destroy);
594 SYSCALL_MAP (io_submit);
595 SYSCALL_MAP (io_cancel);
596 SYSCALL_MAP (io_getevents);
597 SYSCALL_MAP (setxattr);
598 SYSCALL_MAP (lsetxattr);
599 SYSCALL_MAP (fsetxattr);
600 SYSCALL_MAP (getxattr);
601 SYSCALL_MAP (lgetxattr);
602 SYSCALL_MAP (fgetxattr);
603 SYSCALL_MAP (listxattr);
604 SYSCALL_MAP (llistxattr);
605 SYSCALL_MAP (flistxattr);
606 SYSCALL_MAP (removexattr);
607 SYSCALL_MAP (lremovexattr);
608 SYSCALL_MAP (fremovexattr);
609 SYSCALL_MAP (getcwd);
610 SYSCALL_MAP (lookup_dcookie);
611 SYSCALL_MAP (eventfd2);
612 SYSCALL_MAP (epoll_create1);
613 SYSCALL_MAP (epoll_ctl);
614 SYSCALL_MAP (epoll_pwait);
615 SYSCALL_MAP (dup);
616 SYSCALL_MAP (dup3);
617 SYSCALL_MAP (fcntl);
618 SYSCALL_MAP (inotify_init1);
619 SYSCALL_MAP (inotify_add_watch);
620 SYSCALL_MAP (inotify_rm_watch);
621 SYSCALL_MAP (ioctl);
622 SYSCALL_MAP (ioprio_set);
623 SYSCALL_MAP (ioprio_get);
624 SYSCALL_MAP (flock);
625 SYSCALL_MAP (mknodat);
626 SYSCALL_MAP (mkdirat);
627 SYSCALL_MAP (unlinkat);
628 SYSCALL_MAP (symlinkat);
629 SYSCALL_MAP (linkat);
630 UNSUPPORTED_SYSCALL_MAP (umount2);
631 SYSCALL_MAP (mount);
632 SYSCALL_MAP (pivot_root);
633 SYSCALL_MAP (nfsservctl);
634 SYSCALL_MAP (statfs);
635 SYSCALL_MAP (truncate);
636 SYSCALL_MAP (ftruncate);
637 SYSCALL_MAP (fallocate);
638 SYSCALL_MAP (faccessat);
639 SYSCALL_MAP (fchdir);
640 SYSCALL_MAP (chroot);
641 SYSCALL_MAP (fchmod);
642 SYSCALL_MAP (fchmodat);
643 SYSCALL_MAP (fchownat);
644 SYSCALL_MAP (fchown);
645 SYSCALL_MAP (openat);
646 SYSCALL_MAP (close);
647 SYSCALL_MAP (vhangup);
648 SYSCALL_MAP (pipe2);
649 SYSCALL_MAP (quotactl);
650 SYSCALL_MAP (getdents64);
651 SYSCALL_MAP (lseek);
652 SYSCALL_MAP (read);
653 SYSCALL_MAP (write);
654 SYSCALL_MAP (readv);
655 SYSCALL_MAP (writev);
656 SYSCALL_MAP (pread64);
657 SYSCALL_MAP (pwrite64);
658 UNSUPPORTED_SYSCALL_MAP (preadv);
659 UNSUPPORTED_SYSCALL_MAP (pwritev);
660 SYSCALL_MAP (sendfile);
661 SYSCALL_MAP (pselect6);
662 SYSCALL_MAP (ppoll);
663 UNSUPPORTED_SYSCALL_MAP (signalfd4);
664 SYSCALL_MAP (vmsplice);
665 SYSCALL_MAP (splice);
666 SYSCALL_MAP (tee);
667 SYSCALL_MAP (readlinkat);
668 SYSCALL_MAP (newfstatat);
669 SYSCALL_MAP (fstat);
670 SYSCALL_MAP (sync);
671 SYSCALL_MAP (fsync);
672 SYSCALL_MAP (fdatasync);
673 SYSCALL_MAP (sync_file_range);
674 UNSUPPORTED_SYSCALL_MAP (timerfd_create);
675 UNSUPPORTED_SYSCALL_MAP (timerfd_settime);
676 UNSUPPORTED_SYSCALL_MAP (timerfd_gettime);
677 UNSUPPORTED_SYSCALL_MAP (utimensat);
678 SYSCALL_MAP (acct);
679 SYSCALL_MAP (capget);
680 SYSCALL_MAP (capset);
681 SYSCALL_MAP (personality);
682 SYSCALL_MAP (exit);
683 SYSCALL_MAP (exit_group);
684 SYSCALL_MAP (waitid);
685 SYSCALL_MAP (set_tid_address);
686 SYSCALL_MAP (unshare);
687 SYSCALL_MAP (futex);
688 SYSCALL_MAP (set_robust_list);
689 SYSCALL_MAP (get_robust_list);
690 SYSCALL_MAP (nanosleep);
691 SYSCALL_MAP (getitimer);
692 SYSCALL_MAP (setitimer);
693 SYSCALL_MAP (kexec_load);
694 SYSCALL_MAP (init_module);
695 SYSCALL_MAP (delete_module);
696 SYSCALL_MAP (timer_create);
697 SYSCALL_MAP (timer_settime);
698 SYSCALL_MAP (timer_gettime);
699 SYSCALL_MAP (timer_getoverrun);
700 SYSCALL_MAP (timer_delete);
701 SYSCALL_MAP (clock_settime);
702 SYSCALL_MAP (clock_gettime);
703 SYSCALL_MAP (clock_getres);
704 SYSCALL_MAP (clock_nanosleep);
705 SYSCALL_MAP (syslog);
706 SYSCALL_MAP (ptrace);
707 SYSCALL_MAP (sched_setparam);
708 SYSCALL_MAP (sched_setscheduler);
709 SYSCALL_MAP (sched_getscheduler);
710 SYSCALL_MAP (sched_getparam);
711 SYSCALL_MAP (sched_setaffinity);
712 SYSCALL_MAP (sched_getaffinity);
713 SYSCALL_MAP (sched_yield);
714 SYSCALL_MAP (sched_get_priority_max);
715 SYSCALL_MAP (sched_get_priority_min);
716 SYSCALL_MAP (sched_rr_get_interval);
717 SYSCALL_MAP (kill);
718 SYSCALL_MAP (tkill);
719 SYSCALL_MAP (tgkill);
720 SYSCALL_MAP (sigaltstack);
721 SYSCALL_MAP (rt_sigsuspend);
722 SYSCALL_MAP (rt_sigaction);
723 SYSCALL_MAP (rt_sigprocmask);
724 SYSCALL_MAP (rt_sigpending);
725 SYSCALL_MAP (rt_sigtimedwait);
726 SYSCALL_MAP (rt_sigqueueinfo);
727 SYSCALL_MAP (rt_sigreturn);
728 SYSCALL_MAP (setpriority);
729 SYSCALL_MAP (getpriority);
730 SYSCALL_MAP (reboot);
731 SYSCALL_MAP (setregid);
732 SYSCALL_MAP (setgid);
733 SYSCALL_MAP (setreuid);
734 SYSCALL_MAP (setuid);
735 SYSCALL_MAP (setresuid);
736 SYSCALL_MAP (getresuid);
737 SYSCALL_MAP (setresgid);
738 SYSCALL_MAP (getresgid);
739 SYSCALL_MAP (setfsuid);
740 SYSCALL_MAP (setfsgid);
741 SYSCALL_MAP (times);
742 SYSCALL_MAP (setpgid);
743 SYSCALL_MAP (getpgid);
744 SYSCALL_MAP (getsid);
745 SYSCALL_MAP (setsid);
746 SYSCALL_MAP (getgroups);
747 SYSCALL_MAP (setgroups);
748 SYSCALL_MAP (uname);
749 SYSCALL_MAP (sethostname);
750 SYSCALL_MAP (setdomainname);
751 SYSCALL_MAP (getrusage);
752 SYSCALL_MAP (umask);
753 SYSCALL_MAP (prctl);
754 SYSCALL_MAP (getcpu);
755 SYSCALL_MAP (gettimeofday);
756 SYSCALL_MAP (settimeofday);
757 SYSCALL_MAP (adjtimex);
758 SYSCALL_MAP (getpid);
759 SYSCALL_MAP (getppid);
760 SYSCALL_MAP (getuid);
761 SYSCALL_MAP (geteuid);
762 SYSCALL_MAP (getgid);
763 SYSCALL_MAP (getegid);
764 SYSCALL_MAP (gettid);
765 SYSCALL_MAP (sysinfo);
766 SYSCALL_MAP (mq_open);
767 SYSCALL_MAP (mq_unlink);
768 SYSCALL_MAP (mq_timedsend);
769 SYSCALL_MAP (mq_timedreceive);
770 SYSCALL_MAP (mq_notify);
771 SYSCALL_MAP (mq_getsetattr);
772 SYSCALL_MAP (msgget);
773 SYSCALL_MAP (msgctl);
774 SYSCALL_MAP (msgrcv);
775 SYSCALL_MAP (msgsnd);
776 SYSCALL_MAP (semget);
777 SYSCALL_MAP (semctl);
778 SYSCALL_MAP (semtimedop);
779 SYSCALL_MAP (semop);
780 SYSCALL_MAP (shmget);
781 SYSCALL_MAP (shmctl);
782 SYSCALL_MAP (shmat);
783 SYSCALL_MAP (shmdt);
784 SYSCALL_MAP (socket);
785 SYSCALL_MAP (socketpair);
786 SYSCALL_MAP (bind);
787 SYSCALL_MAP (listen);
788 SYSCALL_MAP (accept);
789 SYSCALL_MAP (connect);
790 SYSCALL_MAP (getsockname);
791 SYSCALL_MAP (getpeername);
792 SYSCALL_MAP (sendto);
793 SYSCALL_MAP (recvfrom);
794 SYSCALL_MAP (setsockopt);
795 SYSCALL_MAP (getsockopt);
796 SYSCALL_MAP (shutdown);
797 SYSCALL_MAP (sendmsg);
798 SYSCALL_MAP (recvmsg);
799 SYSCALL_MAP (readahead);
800 SYSCALL_MAP (brk);
801 SYSCALL_MAP (munmap);
802 SYSCALL_MAP (mremap);
803 SYSCALL_MAP (add_key);
804 SYSCALL_MAP (request_key);
805 SYSCALL_MAP (keyctl);
806 SYSCALL_MAP (clone);
807 SYSCALL_MAP (execve);
809 case loongarch_sys_mmap:
810 return gdb_sys_mmap2;
812 SYSCALL_MAP (fadvise64);
813 SYSCALL_MAP (swapon);
814 SYSCALL_MAP (swapoff);
815 SYSCALL_MAP (mprotect);
816 SYSCALL_MAP (msync);
817 SYSCALL_MAP (mlock);
818 SYSCALL_MAP (munlock);
819 SYSCALL_MAP (mlockall);
820 SYSCALL_MAP (munlockall);
821 SYSCALL_MAP (mincore);
822 SYSCALL_MAP (madvise);
823 SYSCALL_MAP (remap_file_pages);
824 SYSCALL_MAP (mbind);
825 SYSCALL_MAP (get_mempolicy);
826 SYSCALL_MAP (set_mempolicy);
827 SYSCALL_MAP (migrate_pages);
828 SYSCALL_MAP (move_pages);
829 UNSUPPORTED_SYSCALL_MAP (rt_tgsigqueueinfo);
830 UNSUPPORTED_SYSCALL_MAP (perf_event_open);
831 UNSUPPORTED_SYSCALL_MAP (accept4);
832 UNSUPPORTED_SYSCALL_MAP (recvmmsg);
833 SYSCALL_MAP (wait4);
834 UNSUPPORTED_SYSCALL_MAP (prlimit64);
835 UNSUPPORTED_SYSCALL_MAP (fanotify_init);
836 UNSUPPORTED_SYSCALL_MAP (fanotify_mark);
837 UNSUPPORTED_SYSCALL_MAP (name_to_handle_at);
838 UNSUPPORTED_SYSCALL_MAP (open_by_handle_at);
839 UNSUPPORTED_SYSCALL_MAP (clock_adjtime);
840 UNSUPPORTED_SYSCALL_MAP (syncfs);
841 UNSUPPORTED_SYSCALL_MAP (setns);
842 UNSUPPORTED_SYSCALL_MAP (sendmmsg);
843 UNSUPPORTED_SYSCALL_MAP (process_vm_readv);
844 UNSUPPORTED_SYSCALL_MAP (process_vm_writev);
845 UNSUPPORTED_SYSCALL_MAP (kcmp);
846 UNSUPPORTED_SYSCALL_MAP (finit_module);
847 UNSUPPORTED_SYSCALL_MAP (sched_setattr);
848 UNSUPPORTED_SYSCALL_MAP (sched_getattr);
849 UNSUPPORTED_SYSCALL_MAP (renameat2);
850 UNSUPPORTED_SYSCALL_MAP (seccomp);
851 SYSCALL_MAP (getrandom);
852 UNSUPPORTED_SYSCALL_MAP (memfd_create);
853 UNSUPPORTED_SYSCALL_MAP (bpf);
854 UNSUPPORTED_SYSCALL_MAP (execveat);
855 UNSUPPORTED_SYSCALL_MAP (userfaultfd);
856 UNSUPPORTED_SYSCALL_MAP (membarrier);
857 UNSUPPORTED_SYSCALL_MAP (mlock2);
858 UNSUPPORTED_SYSCALL_MAP (copy_file_range);
859 UNSUPPORTED_SYSCALL_MAP (preadv2);
860 UNSUPPORTED_SYSCALL_MAP (pwritev2);
861 UNSUPPORTED_SYSCALL_MAP (pkey_mprotect);
862 UNSUPPORTED_SYSCALL_MAP (pkey_alloc);
863 UNSUPPORTED_SYSCALL_MAP (pkey_free);
864 SYSCALL_MAP (statx);
865 UNSUPPORTED_SYSCALL_MAP (io_pgetevents);
866 UNSUPPORTED_SYSCALL_MAP (rseq);
867 UNSUPPORTED_SYSCALL_MAP (kexec_file_load);
868 UNSUPPORTED_SYSCALL_MAP (pidfd_send_signal);
869 UNSUPPORTED_SYSCALL_MAP (io_uring_setup);
870 UNSUPPORTED_SYSCALL_MAP (io_uring_enter);
871 UNSUPPORTED_SYSCALL_MAP (io_uring_register);
872 UNSUPPORTED_SYSCALL_MAP (open_tree);
873 UNSUPPORTED_SYSCALL_MAP (move_mount);
874 UNSUPPORTED_SYSCALL_MAP (fsopen);
875 UNSUPPORTED_SYSCALL_MAP (fsconfig);
876 UNSUPPORTED_SYSCALL_MAP (fsmount);
877 UNSUPPORTED_SYSCALL_MAP (fspick);
878 UNSUPPORTED_SYSCALL_MAP (pidfd_open);
879 UNSUPPORTED_SYSCALL_MAP (clone3);
880 UNSUPPORTED_SYSCALL_MAP (close_range);
881 UNSUPPORTED_SYSCALL_MAP (openat2);
882 UNSUPPORTED_SYSCALL_MAP (pidfd_getfd);
883 UNSUPPORTED_SYSCALL_MAP (faccessat2);
884 UNSUPPORTED_SYSCALL_MAP (process_madvise);
885 UNSUPPORTED_SYSCALL_MAP (epoll_pwait2);
886 UNSUPPORTED_SYSCALL_MAP (mount_setattr);
887 UNSUPPORTED_SYSCALL_MAP (quotactl_fd);
888 UNSUPPORTED_SYSCALL_MAP (landlock_create_ruleset);
889 UNSUPPORTED_SYSCALL_MAP (landlock_add_rule);
890 UNSUPPORTED_SYSCALL_MAP (landlock_restrict_self);
891 UNSUPPORTED_SYSCALL_MAP (process_mrelease);
892 UNSUPPORTED_SYSCALL_MAP (futex_waitv);
893 UNSUPPORTED_SYSCALL_MAP (set_mempolicy_home_node);
894 UNSUPPORTED_SYSCALL_MAP (cachestat);
895 UNSUPPORTED_SYSCALL_MAP (fchmodat2);
896 UNSUPPORTED_SYSCALL_MAP (map_shadow_stack);
897 UNSUPPORTED_SYSCALL_MAP (futex_wake);
898 UNSUPPORTED_SYSCALL_MAP (futex_wait);
899 UNSUPPORTED_SYSCALL_MAP (futex_requeue);
900 UNSUPPORTED_SYSCALL_MAP (statmount);
901 UNSUPPORTED_SYSCALL_MAP (listmount);
902 UNSUPPORTED_SYSCALL_MAP (lsm_get_self_attr);
903 UNSUPPORTED_SYSCALL_MAP (lsm_set_self_attr);
904 UNSUPPORTED_SYSCALL_MAP (lsm_list_modules);
905 UNSUPPORTED_SYSCALL_MAP (mseal);
906 UNSUPPORTED_SYSCALL_MAP (syscalls);
907 default:
908 return gdb_sys_no_syscall;
910 #undef SYSCALL_MAP
911 #undef UNSUPPORTED_SYSCALL_MAP
914 static int
915 loongarch_record_all_but_pc_registers (struct regcache *regcache)
918 /* Record General purpose Registers. */
919 for (int i = 0; i < 32; ++i)
920 if (record_full_arch_list_add_reg (regcache, i))
921 return -1;
923 /* Record orig_a0 */
924 if (record_full_arch_list_add_reg (regcache, LOONGARCH_ORIG_A0_REGNUM))
925 return -1;
927 /* Record badvaddr */
928 if (record_full_arch_list_add_reg (regcache, LOONGARCH_BADV_REGNUM))
929 return -1;
931 return 0;
934 /* Handler for LoongArch architechture system call instruction recording. */
936 static int
937 loongarch_linux_syscall_record (struct regcache *regcache,
938 unsigned long syscall_number)
940 int ret = 0;
941 enum gdb_syscall syscall_gdb;
943 syscall_gdb =
944 loongarch_canonicalize_syscall ((enum loongarch_syscall) syscall_number);
946 if (syscall_gdb < 0)
948 gdb_printf (gdb_stderr,
949 _("Process record and replay target doesn't "
950 "support syscall number %s\n"), plongest (syscall_number));
951 return -1;
954 if (syscall_gdb == gdb_sys_sigreturn || syscall_gdb == gdb_sys_rt_sigreturn)
955 return loongarch_record_all_but_pc_registers (regcache);
957 ret = record_linux_system_call (syscall_gdb, regcache,
958 &loongarch_linux_record_tdep);
960 if (ret != 0)
961 return ret;
963 /* Record the return value of the system call. */
964 if (record_full_arch_list_add_reg (regcache, LOONGARCH_A0_REGNUM))
965 return -1;
967 return 0;
970 /* Initialize the loongarch_linux_record_tdep. These values are the size
971 of the type that will be used in a system call. They are obtained from
972 Linux Kernel source. */
974 static void
975 init_loongarch_linux_record_tdep (struct gdbarch *gdbarch)
977 loongarch_linux_record_tdep.size_pointer
978 = gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT;
979 loongarch_linux_record_tdep.size_tms = 32;
980 loongarch_linux_record_tdep.size_loff_t = 8;
981 loongarch_linux_record_tdep.size_flock = 32;
982 loongarch_linux_record_tdep.size_oldold_utsname = 45;
983 loongarch_linux_record_tdep.size_ustat = 32;
984 loongarch_linux_record_tdep.size_old_sigaction = 32;
985 loongarch_linux_record_tdep.size_old_sigset_t = 8;
986 loongarch_linux_record_tdep.size_rlimit = 16;
987 loongarch_linux_record_tdep.size_rusage = 144;
988 loongarch_linux_record_tdep.size_timeval = 16;
989 loongarch_linux_record_tdep.size_timezone = 8;
990 loongarch_linux_record_tdep.size_old_gid_t = 4;
991 loongarch_linux_record_tdep.size_old_uid_t = 4;
992 loongarch_linux_record_tdep.size_fd_set = 128;
993 loongarch_linux_record_tdep.size_old_dirent = 280;
994 loongarch_linux_record_tdep.size_statfs = 120;
995 loongarch_linux_record_tdep.size_statfs64 = 120;
996 loongarch_linux_record_tdep.size_sockaddr = 16;
997 loongarch_linux_record_tdep.size_int
998 = gdbarch_int_bit (gdbarch) / TARGET_CHAR_BIT;
999 loongarch_linux_record_tdep.size_long
1000 = gdbarch_long_bit (gdbarch) / TARGET_CHAR_BIT;
1001 loongarch_linux_record_tdep.size_ulong
1002 = gdbarch_long_bit (gdbarch) / TARGET_CHAR_BIT;
1003 loongarch_linux_record_tdep.size_msghdr = 56;
1004 loongarch_linux_record_tdep.size_itimerval = 32;
1005 loongarch_linux_record_tdep.size_stat = 144;
1006 loongarch_linux_record_tdep.size_old_utsname = 325;
1007 loongarch_linux_record_tdep.size_sysinfo = 112;
1008 loongarch_linux_record_tdep.size_msqid_ds = 120;
1009 loongarch_linux_record_tdep.size_shmid_ds = 112;
1010 loongarch_linux_record_tdep.size_new_utsname = 390;
1011 loongarch_linux_record_tdep.size_timex = 208;
1012 loongarch_linux_record_tdep.size_mem_dqinfo = 72;
1013 loongarch_linux_record_tdep.size_if_dqblk = 72;
1014 loongarch_linux_record_tdep.size_fs_quota_stat = 80;
1015 loongarch_linux_record_tdep.size_timespec = 16;
1016 loongarch_linux_record_tdep.size_pollfd = 8;
1017 loongarch_linux_record_tdep.size_NFS_FHSIZE = 32;
1018 loongarch_linux_record_tdep.size_knfsd_fh = 132;
1019 loongarch_linux_record_tdep.size_TASK_COMM_LEN = 16;
1020 loongarch_linux_record_tdep.size_sigaction = 24;
1021 loongarch_linux_record_tdep.size_sigset_t = 8;
1022 loongarch_linux_record_tdep.size_siginfo_t = 128;
1023 loongarch_linux_record_tdep.size_cap_user_data_t = 8;
1024 loongarch_linux_record_tdep.size_stack_t = 24;
1025 loongarch_linux_record_tdep.size_off_t = 8;
1026 loongarch_linux_record_tdep.size_stat64 = 144;
1027 loongarch_linux_record_tdep.size_gid_t = 4;
1028 loongarch_linux_record_tdep.size_uid_t = 4;
1029 loongarch_linux_record_tdep.size_PAGE_SIZE = 0x4000;
1030 loongarch_linux_record_tdep.size_flock64 = 32;
1031 loongarch_linux_record_tdep.size_user_desc = 16;
1032 loongarch_linux_record_tdep.size_io_event = 32;
1033 loongarch_linux_record_tdep.size_iocb = 64;
1034 loongarch_linux_record_tdep.size_epoll_event = 12;
1035 loongarch_linux_record_tdep.size_itimerspec = 32;
1036 loongarch_linux_record_tdep.size_mq_attr = 64;
1037 loongarch_linux_record_tdep.size_termios = 36;
1038 loongarch_linux_record_tdep.size_termios2 = 44;
1039 loongarch_linux_record_tdep.size_pid_t = 4;
1040 loongarch_linux_record_tdep.size_winsize = 8;
1041 loongarch_linux_record_tdep.size_serial_struct = 72;
1042 loongarch_linux_record_tdep.size_serial_icounter_struct = 80;
1043 loongarch_linux_record_tdep.size_hayes_esp_config = 12;
1044 loongarch_linux_record_tdep.size_size_t = 8;
1045 loongarch_linux_record_tdep.size_iovec = 16;
1046 loongarch_linux_record_tdep.size_time_t = 8;
1048 /* These values are the second argument of system call "sys_ioctl".
1049 They are obtained from Linux Kernel source. */
1050 loongarch_linux_record_tdep.ioctl_TCGETS = 0x5401;
1051 loongarch_linux_record_tdep.ioctl_TCSETS = 0x5402;
1052 loongarch_linux_record_tdep.ioctl_TCSETSW = 0x5403;
1053 loongarch_linux_record_tdep.ioctl_TCSETSF = 0x5404;
1054 loongarch_linux_record_tdep.ioctl_TCGETA = 0x5405;
1055 loongarch_linux_record_tdep.ioctl_TCSETA = 0x5406;
1056 loongarch_linux_record_tdep.ioctl_TCSETAW = 0x5407;
1057 loongarch_linux_record_tdep.ioctl_TCSETAF = 0x5408;
1058 loongarch_linux_record_tdep.ioctl_TCSBRK = 0x5409;
1059 loongarch_linux_record_tdep.ioctl_TCXONC = 0x540a;
1060 loongarch_linux_record_tdep.ioctl_TCFLSH = 0x540b;
1061 loongarch_linux_record_tdep.ioctl_TIOCEXCL = 0x540c;
1062 loongarch_linux_record_tdep.ioctl_TIOCNXCL = 0x540d;
1063 loongarch_linux_record_tdep.ioctl_TIOCSCTTY = 0x540e;
1064 loongarch_linux_record_tdep.ioctl_TIOCGPGRP = 0x540f;
1065 loongarch_linux_record_tdep.ioctl_TIOCSPGRP = 0x5410;
1066 loongarch_linux_record_tdep.ioctl_TIOCOUTQ = 0x5411;
1067 loongarch_linux_record_tdep.ioctl_TIOCSTI = 0x5412;
1068 loongarch_linux_record_tdep.ioctl_TIOCGWINSZ = 0x5413;
1069 loongarch_linux_record_tdep.ioctl_TIOCSWINSZ = 0x5414;
1070 loongarch_linux_record_tdep.ioctl_TIOCMGET = 0x5415;
1071 loongarch_linux_record_tdep.ioctl_TIOCMBIS = 0x5416;
1072 loongarch_linux_record_tdep.ioctl_TIOCMBIC = 0x5417;
1073 loongarch_linux_record_tdep.ioctl_TIOCMSET = 0x5418;
1074 loongarch_linux_record_tdep.ioctl_TIOCGSOFTCAR = 0x5419;
1075 loongarch_linux_record_tdep.ioctl_TIOCSSOFTCAR = 0x541a;
1076 loongarch_linux_record_tdep.ioctl_FIONREAD = 0x541b;
1077 loongarch_linux_record_tdep.ioctl_TIOCINQ = 0x541b;
1078 loongarch_linux_record_tdep.ioctl_TIOCLINUX = 0x541c;
1079 loongarch_linux_record_tdep.ioctl_TIOCCONS = 0x541d;
1080 loongarch_linux_record_tdep.ioctl_TIOCGSERIAL = 0x541e;
1081 loongarch_linux_record_tdep.ioctl_TIOCSSERIAL = 0x541f;
1082 loongarch_linux_record_tdep.ioctl_TIOCPKT = 0x5420;
1083 loongarch_linux_record_tdep.ioctl_FIONBIO = 0x5421;
1084 loongarch_linux_record_tdep.ioctl_TIOCNOTTY = 0x5422;
1085 loongarch_linux_record_tdep.ioctl_TIOCSETD = 0x5423;
1086 loongarch_linux_record_tdep.ioctl_TIOCGETD = 0x5424;
1087 loongarch_linux_record_tdep.ioctl_TCSBRKP = 0x5425;
1088 loongarch_linux_record_tdep.ioctl_TIOCTTYGSTRUCT = 0x5426;
1089 loongarch_linux_record_tdep.ioctl_TIOCSBRK = 0x5427;
1090 loongarch_linux_record_tdep.ioctl_TIOCCBRK = 0x5428;
1091 loongarch_linux_record_tdep.ioctl_TIOCGSID = 0x5429;
1092 loongarch_linux_record_tdep.ioctl_TCGETS2 = 0x802c542a;
1093 loongarch_linux_record_tdep.ioctl_TCSETS2 = 0x402c542b;
1094 loongarch_linux_record_tdep.ioctl_TCSETSW2 = 0x402c542c;
1095 loongarch_linux_record_tdep.ioctl_TCSETSF2 = 0x402c542d;
1096 loongarch_linux_record_tdep.ioctl_TIOCGPTN = 0x80045430;
1097 loongarch_linux_record_tdep.ioctl_TIOCSPTLCK = 0x40045431;
1098 loongarch_linux_record_tdep.ioctl_FIONCLEX = 0x5450;
1099 loongarch_linux_record_tdep.ioctl_FIOCLEX = 0x5451;
1100 loongarch_linux_record_tdep.ioctl_FIOASYNC = 0x5452;
1101 loongarch_linux_record_tdep.ioctl_TIOCSERCONFIG = 0x5453;
1102 loongarch_linux_record_tdep.ioctl_TIOCSERGWILD = 0x5454;
1103 loongarch_linux_record_tdep.ioctl_TIOCSERSWILD = 0x5455;
1104 loongarch_linux_record_tdep.ioctl_TIOCGLCKTRMIOS = 0x5456;
1105 loongarch_linux_record_tdep.ioctl_TIOCSLCKTRMIOS = 0x5457;
1106 loongarch_linux_record_tdep.ioctl_TIOCSERGSTRUCT = 0x5458;
1107 loongarch_linux_record_tdep.ioctl_TIOCSERGETLSR = 0x5459;
1108 loongarch_linux_record_tdep.ioctl_TIOCSERGETMULTI = 0x545a;
1109 loongarch_linux_record_tdep.ioctl_TIOCSERSETMULTI = 0x545b;
1110 loongarch_linux_record_tdep.ioctl_TIOCMIWAIT = 0x545c;
1111 loongarch_linux_record_tdep.ioctl_TIOCGICOUNT = 0x545d;
1112 loongarch_linux_record_tdep.ioctl_TIOCGHAYESESP = 0x545e;
1113 loongarch_linux_record_tdep.ioctl_TIOCSHAYESESP = 0x545f;
1114 loongarch_linux_record_tdep.ioctl_FIOQSIZE = 0x5460;
1116 /* These values are the second argument of system call "sys_fcntl"
1117 and "sys_fcntl64". They are obtained from Linux Kernel source. */
1118 loongarch_linux_record_tdep.fcntl_F_GETLK = 5;
1119 loongarch_linux_record_tdep.fcntl_F_GETLK64 = 12;
1120 loongarch_linux_record_tdep.fcntl_F_SETLK64 = 13;
1121 loongarch_linux_record_tdep.fcntl_F_SETLKW64 = 14;
1123 loongarch_linux_record_tdep.arg1 = LOONGARCH_A0_REGNUM + 0;
1124 loongarch_linux_record_tdep.arg2 = LOONGARCH_A0_REGNUM + 1;
1125 loongarch_linux_record_tdep.arg3 = LOONGARCH_A0_REGNUM + 2;
1126 loongarch_linux_record_tdep.arg4 = LOONGARCH_A0_REGNUM + 3;
1127 loongarch_linux_record_tdep.arg5 = LOONGARCH_A0_REGNUM + 4;
1128 loongarch_linux_record_tdep.arg6 = LOONGARCH_A0_REGNUM + 5;
1129 loongarch_linux_record_tdep.arg7 = LOONGARCH_A0_REGNUM + 6;
1132 /* Initialize LoongArch Linux ABI info. */
1134 static void
1135 loongarch_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
1137 loongarch_gdbarch_tdep *tdep = gdbarch_tdep<loongarch_gdbarch_tdep> (gdbarch);
1139 linux_init_abi (info, gdbarch, 0);
1141 set_solib_svr4_fetch_link_map_offsets (gdbarch,
1142 info.bfd_arch_info->bits_per_address == 32
1143 ? linux_ilp32_fetch_link_map_offsets
1144 : linux_lp64_fetch_link_map_offsets);
1146 /* GNU/Linux uses SVR4-style shared libraries. */
1147 set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
1149 /* GNU/Linux uses the dynamic linker included in the GNU C Library. */
1150 set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
1152 /* Enable TLS support. */
1153 set_gdbarch_fetch_tls_load_module_address (gdbarch, svr4_fetch_objfile_link_map);
1155 /* Prepend tramp frame unwinder for signal. */
1156 tramp_frame_prepend_unwinder (gdbarch, &loongarch_linux_rt_sigframe);
1158 /* Core file support. */
1159 set_gdbarch_iterate_over_regset_sections (gdbarch, loongarch_iterate_over_regset_sections);
1161 tdep->syscall_next_pc = loongarch_linux_syscall_next_pc;
1163 /* Set the correct XML syscall filename. */
1164 set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_LOONGARCH);
1166 /* Get the syscall number from the arch's register. */
1167 set_gdbarch_get_syscall_number (gdbarch, loongarch_linux_get_syscall_number);
1169 /* Reversible debugging, process record. */
1170 set_gdbarch_process_record (gdbarch, loongarch_process_record);
1172 /* Syscall record. */
1173 tdep->loongarch_syscall_record = loongarch_linux_syscall_record;
1174 init_loongarch_linux_record_tdep (gdbarch);
1177 /* Initialize LoongArch Linux target support. */
1179 void _initialize_loongarch_linux_tdep ();
1180 void
1181 _initialize_loongarch_linux_tdep ()
1183 gdbarch_register_osabi (bfd_arch_loongarch, bfd_mach_loongarch32,
1184 GDB_OSABI_LINUX, loongarch_linux_init_abi);
1185 gdbarch_register_osabi (bfd_arch_loongarch, bfd_mach_loongarch64,
1186 GDB_OSABI_LINUX, loongarch_linux_init_abi);