bfin-linux-tdep.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /* Target-dependent code for Analog Devices Blackfin processor, for GDB.
  2. Copyright (C) 2005-2022 Free Software Foundation, Inc.
  3. Contributed by Analog Devices, Inc.
  4. This file is part of GDB.
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  15. #include "defs.h"
  16. #include "arch-utils.h"
  17. #include "regcache.h"
  18. #include "tramp-frame.h"
  19. #include "trad-frame.h"
  20. #include "osabi.h"
  21. #include "xml-syscall.h"
  22. #include "linux-tdep.h"
  23. #include "bfin-tdep.h"
  24. /* From <asm/sigcontext.h>. */
  25. #define SIGCONTEXT_OFFSET 168
  26. static const int bfin_linux_sigcontext_reg_offset[BFIN_NUM_REGS] =
  27. {
  28. 0 * 4, /* %r0 */
  29. 1 * 4, /* %r1 */
  30. 2 * 4, /* %r2 */
  31. 3 * 4, /* %r3 */
  32. 4 * 4, /* %r4 */
  33. 5 * 4, /* %r5 */
  34. 6 * 4, /* %r6 */
  35. 7 * 4, /* %r7 */
  36. 8 * 4, /* %p0 */
  37. 9 * 4, /* %p1 */
  38. 10 * 4, /* %p2 */
  39. 11 * 4, /* %p3 */
  40. 12 * 4, /* %p4 */
  41. 13 * 4, /* %p5 */
  42. 14 * 4, /* %sp */
  43. 23 * 4, /* %fp */
  44. 24 * 4, /* %i0 */
  45. 25 * 4, /* %i1 */
  46. 26 * 4, /* %i2 */
  47. 27 * 4, /* %i3 */
  48. 28 * 4, /* %m0 */
  49. 29 * 4, /* %m1 */
  50. 30 * 4, /* %m2 */
  51. 31 * 4, /* %m3 */
  52. 36 * 4, /* %b0 */
  53. 37 * 4, /* %b1 */
  54. 38 * 4, /* %b2 */
  55. 39 * 4, /* %b3 */
  56. 32 * 4, /* %l0 */
  57. 33 * 4, /* %l1 */
  58. 34 * 4, /* %l2 */
  59. 35 * 4, /* %l3 */
  60. 17 * 4, /* %a0x */
  61. 15 * 4, /* %a0w */
  62. 18 * 4, /* %a1x */
  63. 16 * 4, /* %a1w */
  64. 19 * 4, /* %astat */
  65. 20 * 4, /* %rets */
  66. 40 * 4, /* %lc0 */
  67. 42 * 4, /* %lt0 */
  68. 44 * 4, /* %lb0 */
  69. 41 * 4, /* %lc1 */
  70. 43 * 4, /* %lt1 */
  71. 45 * 4, /* %lb1 */
  72. -1, /* %cycles */
  73. -1, /* %cycles2 */
  74. -1, /* %usp */
  75. 46 * 4, /* %seqstat */
  76. -1, /* syscfg */
  77. 21 * 4, /* %reti */
  78. 22 * 4, /* %retx */
  79. -1, /* %retn */
  80. -1, /* %rete */
  81. 21 * 4, /* %pc */
  82. };
  83. /* Signal trampolines. */
  84. static void
  85. bfin_linux_sigframe_init (const struct tramp_frame *self,
  86. struct frame_info *this_frame,
  87. struct trad_frame_cache *this_cache,
  88. CORE_ADDR func)
  89. {
  90. CORE_ADDR sp = get_frame_sp (this_frame);
  91. CORE_ADDR pc = get_frame_pc (this_frame);
  92. CORE_ADDR sigcontext = sp + SIGCONTEXT_OFFSET;
  93. const int *reg_offset = bfin_linux_sigcontext_reg_offset;
  94. int i;
  95. for (i = 0; i < BFIN_NUM_REGS; i++)
  96. if (reg_offset[i] != -1)
  97. trad_frame_set_reg_addr (this_cache, i, sigcontext + reg_offset[i]);
  98. /* This would come after the LINK instruction in the ret_from_signal
  99. function, hence the frame id would be SP + 8. */
  100. trad_frame_set_id (this_cache, frame_id_build (sp + 8, pc));
  101. }
  102. static const struct tramp_frame bfin_linux_sigframe =
  103. {
  104. SIGTRAMP_FRAME,
  105. 4,
  106. {
  107. { 0x00ADE128, 0xffffffff }, /* P0 = __NR_rt_sigreturn; */
  108. { 0x00A0, 0xffff }, /* EXCPT 0; */
  109. { TRAMP_SENTINEL_INSN, ULONGEST_MAX },
  110. },
  111. bfin_linux_sigframe_init,
  112. };
  113. static LONGEST
  114. bfin_linux_get_syscall_number (struct gdbarch *gdbarch,
  115. thread_info *thread)
  116. {
  117. struct regcache *regcache = get_thread_regcache (thread);
  118. enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  119. /* The content of a register. */
  120. gdb_byte buf[4];
  121. /* The result. */
  122. LONGEST ret;
  123. /* Getting the system call number from the register.
  124. When dealing with Blackfin architecture, this information
  125. is stored at %p0 register. */
  126. regcache->cooked_read (BFIN_P0_REGNUM, buf);
  127. ret = extract_signed_integer (buf, 4, byte_order);
  128. return ret;
  129. }
  130. static void
  131. bfin_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
  132. {
  133. linux_init_abi (info, gdbarch, 0);
  134. /* Set the sigtramp frame sniffer. */
  135. tramp_frame_prepend_unwinder (gdbarch, &bfin_linux_sigframe);
  136. /* Functions for 'catch syscall'. */
  137. set_xml_syscall_file_name (gdbarch, "syscalls/bfin-linux.xml");
  138. set_gdbarch_get_syscall_number (gdbarch,
  139. bfin_linux_get_syscall_number);
  140. }
  141. void _initialize_bfin_linux_tdep ();
  142. void
  143. _initialize_bfin_linux_tdep ()
  144. {
  145. gdbarch_register_osabi (bfd_arch_bfin, 0, GDB_OSABI_LINUX,
  146. bfin_linux_init_abi);
  147. }