ptrace.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * arch/arm/include/asm/ptrace.h
  4. *
  5. * Copyright (C) 1996-2003 Russell King
  6. */
  7. #ifndef __ASM_ARM_PTRACE_H
  8. #define __ASM_ARM_PTRACE_H
  9. #include <uapi/asm/ptrace.h>
  10. #ifndef __ASSEMBLY__
  11. #include <linux/types.h>
  12. struct pt_regs {
  13. unsigned long uregs[18];
  14. };
  15. struct svc_pt_regs {
  16. struct pt_regs regs;
  17. u32 dacr;
  18. };
  19. #define to_svc_pt_regs(r) container_of(r, struct svc_pt_regs, regs)
  20. #define user_mode(regs) \
  21. (((regs)->ARM_cpsr & 0xf) == 0)
  22. #ifdef CONFIG_ARM_THUMB
  23. #define thumb_mode(regs) \
  24. (((regs)->ARM_cpsr & PSR_T_BIT))
  25. #else
  26. #define thumb_mode(regs) (0)
  27. #endif
  28. #ifndef CONFIG_CPU_V7M
  29. #define isa_mode(regs) \
  30. ((((regs)->ARM_cpsr & PSR_J_BIT) >> (__ffs(PSR_J_BIT) - 1)) | \
  31. (((regs)->ARM_cpsr & PSR_T_BIT) >> (__ffs(PSR_T_BIT))))
  32. #else
  33. #define isa_mode(regs) 1 /* Thumb */
  34. #endif
  35. #define processor_mode(regs) \
  36. ((regs)->ARM_cpsr & MODE_MASK)
  37. #define interrupts_enabled(regs) \
  38. (!((regs)->ARM_cpsr & PSR_I_BIT))
  39. #define fast_interrupts_enabled(regs) \
  40. (!((regs)->ARM_cpsr & PSR_F_BIT))
  41. /* Are the current registers suitable for user mode?
  42. * (used to maintain security in signal handlers)
  43. */
  44. static inline int valid_user_regs(struct pt_regs *regs)
  45. {
  46. #ifndef CONFIG_CPU_V7M
  47. unsigned long mode = regs->ARM_cpsr & MODE_MASK;
  48. /*
  49. * Always clear the F (FIQ) and A (delayed abort) bits
  50. */
  51. regs->ARM_cpsr &= ~(PSR_F_BIT | PSR_A_BIT);
  52. if ((regs->ARM_cpsr & PSR_I_BIT) == 0) {
  53. if (mode == USR_MODE)
  54. return 1;
  55. if (elf_hwcap & HWCAP_26BIT && mode == USR26_MODE)
  56. return 1;
  57. }
  58. /*
  59. * Force CPSR to something logical...
  60. */
  61. regs->ARM_cpsr &= PSR_f | PSR_s | PSR_x | PSR_T_BIT | MODE32_BIT;
  62. if (!(elf_hwcap & HWCAP_26BIT))
  63. regs->ARM_cpsr |= USR_MODE;
  64. return 0;
  65. #else /* ifndef CONFIG_CPU_V7M */
  66. return 1;
  67. #endif
  68. }
  69. static inline long regs_return_value(struct pt_regs *regs)
  70. {
  71. return regs->ARM_r0;
  72. }
  73. #define instruction_pointer(regs) (regs)->ARM_pc
  74. #ifdef CONFIG_THUMB2_KERNEL
  75. #define frame_pointer(regs) (regs)->ARM_r7
  76. #else
  77. #define frame_pointer(regs) (regs)->ARM_fp
  78. #endif
  79. static inline void instruction_pointer_set(struct pt_regs *regs,
  80. unsigned long val)
  81. {
  82. instruction_pointer(regs) = val;
  83. }
  84. #ifdef CONFIG_SMP
  85. extern unsigned long profile_pc(struct pt_regs *regs);
  86. #else
  87. #define profile_pc(regs) instruction_pointer(regs)
  88. #endif
  89. #define predicate(x) ((x) & 0xf0000000)
  90. #define PREDICATE_ALWAYS 0xe0000000
  91. /*
  92. * True if instr is a 32-bit thumb instruction. This works if instr
  93. * is the first or only half-word of a thumb instruction. It also works
  94. * when instr holds all 32-bits of a wide thumb instruction if stored
  95. * in the form (first_half<<16)|(second_half)
  96. */
  97. #define is_wide_instruction(instr) ((unsigned)(instr) >= 0xe800)
  98. /*
  99. * kprobe-based event tracer support
  100. */
  101. #include <linux/compiler.h>
  102. #define MAX_REG_OFFSET (offsetof(struct pt_regs, ARM_ORIG_r0))
  103. extern int regs_query_register_offset(const char *name);
  104. extern const char *regs_query_register_name(unsigned int offset);
  105. extern bool regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr);
  106. extern unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
  107. unsigned int n);
  108. /**
  109. * regs_get_register() - get register value from its offset
  110. * @regs: pt_regs from which register value is gotten
  111. * @offset: offset number of the register.
  112. *
  113. * regs_get_register returns the value of a register whose offset from @regs.
  114. * The @offset is the offset of the register in struct pt_regs.
  115. * If @offset is bigger than MAX_REG_OFFSET, this returns 0.
  116. */
  117. static inline unsigned long regs_get_register(struct pt_regs *regs,
  118. unsigned int offset)
  119. {
  120. if (unlikely(offset > MAX_REG_OFFSET))
  121. return 0;
  122. return *(unsigned long *)((unsigned long)regs + offset);
  123. }
  124. /* Valid only for Kernel mode traps. */
  125. static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
  126. {
  127. return regs->ARM_sp;
  128. }
  129. static inline unsigned long user_stack_pointer(struct pt_regs *regs)
  130. {
  131. return regs->ARM_sp;
  132. }
  133. #define current_pt_regs(void) ({ (struct pt_regs *) \
  134. ((current_stack_pointer | (THREAD_SIZE - 1)) - 7) - 1; \
  135. })
  136. /*
  137. * Update ITSTATE after normal execution of an IT block instruction.
  138. *
  139. * The 8 IT state bits are split into two parts in CPSR:
  140. * ITSTATE<1:0> are in CPSR<26:25>
  141. * ITSTATE<7:2> are in CPSR<15:10>
  142. */
  143. static inline unsigned long it_advance(unsigned long cpsr)
  144. {
  145. if ((cpsr & 0x06000400) == 0) {
  146. /* ITSTATE<2:0> == 0 means end of IT block, so clear IT state */
  147. cpsr &= ~PSR_IT_MASK;
  148. } else {
  149. /* We need to shift left ITSTATE<4:0> */
  150. const unsigned long mask = 0x06001c00; /* Mask ITSTATE<4:0> */
  151. unsigned long it = cpsr & mask;
  152. it <<= 1;
  153. it |= it >> (27 - 10); /* Carry ITSTATE<2> to correct place */
  154. it &= mask;
  155. cpsr &= ~mask;
  156. cpsr |= it;
  157. }
  158. return cpsr;
  159. }
  160. #endif /* __ASSEMBLY__ */
  161. #endif