Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  *  arch/arm/include/asm/ptrace.h
0004  *
0005  *  Copyright (C) 1996-2003 Russell King
0006  */
0007 #ifndef __ASM_ARM_PTRACE_H
0008 #define __ASM_ARM_PTRACE_H
0009 
0010 #include <uapi/asm/ptrace.h>
0011 
0012 #ifndef __ASSEMBLY__
0013 #include <linux/types.h>
0014 
0015 struct pt_regs {
0016     unsigned long uregs[18];
0017 };
0018 
0019 struct svc_pt_regs {
0020     struct pt_regs regs;
0021     u32 dacr;
0022 };
0023 
0024 #define to_svc_pt_regs(r) container_of(r, struct svc_pt_regs, regs)
0025 
0026 #define user_mode(regs) \
0027     (((regs)->ARM_cpsr & 0xf) == 0)
0028 
0029 #ifdef CONFIG_ARM_THUMB
0030 #define thumb_mode(regs) \
0031     (((regs)->ARM_cpsr & PSR_T_BIT))
0032 #else
0033 #define thumb_mode(regs) (0)
0034 #endif
0035 
0036 #ifndef CONFIG_CPU_V7M
0037 #define isa_mode(regs) \
0038     ((((regs)->ARM_cpsr & PSR_J_BIT) >> (__ffs(PSR_J_BIT) - 1)) | \
0039      (((regs)->ARM_cpsr & PSR_T_BIT) >> (__ffs(PSR_T_BIT))))
0040 #else
0041 #define isa_mode(regs) 1 /* Thumb */
0042 #endif
0043 
0044 #define processor_mode(regs) \
0045     ((regs)->ARM_cpsr & MODE_MASK)
0046 
0047 #define interrupts_enabled(regs) \
0048     (!((regs)->ARM_cpsr & PSR_I_BIT))
0049 
0050 #define fast_interrupts_enabled(regs) \
0051     (!((regs)->ARM_cpsr & PSR_F_BIT))
0052 
0053 /* Are the current registers suitable for user mode?
0054  * (used to maintain security in signal handlers)
0055  */
0056 static inline int valid_user_regs(struct pt_regs *regs)
0057 {
0058 #ifndef CONFIG_CPU_V7M
0059     unsigned long mode = regs->ARM_cpsr & MODE_MASK;
0060 
0061     /*
0062      * Always clear the F (FIQ) and A (delayed abort) bits
0063      */
0064     regs->ARM_cpsr &= ~(PSR_F_BIT | PSR_A_BIT);
0065 
0066     if ((regs->ARM_cpsr & PSR_I_BIT) == 0) {
0067         if (mode == USR_MODE)
0068             return 1;
0069         if (elf_hwcap & HWCAP_26BIT && mode == USR26_MODE)
0070             return 1;
0071     }
0072 
0073     /*
0074      * Force CPSR to something logical...
0075      */
0076     regs->ARM_cpsr &= PSR_f | PSR_s | PSR_x | PSR_T_BIT | MODE32_BIT;
0077     if (!(elf_hwcap & HWCAP_26BIT))
0078         regs->ARM_cpsr |= USR_MODE;
0079 
0080     return 0;
0081 #else /* ifndef CONFIG_CPU_V7M */
0082     return 1;
0083 #endif
0084 }
0085 
0086 static inline long regs_return_value(struct pt_regs *regs)
0087 {
0088     return regs->ARM_r0;
0089 }
0090 
0091 #define instruction_pointer(regs)   (regs)->ARM_pc
0092 
0093 #ifdef CONFIG_THUMB2_KERNEL
0094 #define frame_pointer(regs) (regs)->ARM_r7
0095 #else
0096 #define frame_pointer(regs) (regs)->ARM_fp
0097 #endif
0098 
0099 static inline void instruction_pointer_set(struct pt_regs *regs,
0100                        unsigned long val)
0101 {
0102     instruction_pointer(regs) = val;
0103 }
0104 
0105 #ifdef CONFIG_SMP
0106 extern unsigned long profile_pc(struct pt_regs *regs);
0107 #else
0108 #define profile_pc(regs) instruction_pointer(regs)
0109 #endif
0110 
0111 #define predicate(x)        ((x) & 0xf0000000)
0112 #define PREDICATE_ALWAYS    0xe0000000
0113 
0114 /*
0115  * True if instr is a 32-bit thumb instruction. This works if instr
0116  * is the first or only half-word of a thumb instruction. It also works
0117  * when instr holds all 32-bits of a wide thumb instruction if stored
0118  * in the form (first_half<<16)|(second_half)
0119  */
0120 #define is_wide_instruction(instr)  ((unsigned)(instr) >= 0xe800)
0121 
0122 /*
0123  * kprobe-based event tracer support
0124  */
0125 #include <linux/compiler.h>
0126 #define MAX_REG_OFFSET (offsetof(struct pt_regs, ARM_ORIG_r0))
0127 
0128 extern int regs_query_register_offset(const char *name);
0129 extern const char *regs_query_register_name(unsigned int offset);
0130 extern bool regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr);
0131 extern unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
0132                            unsigned int n);
0133 
0134 /**
0135  * regs_get_register() - get register value from its offset
0136  * @regs:      pt_regs from which register value is gotten
0137  * @offset:    offset number of the register.
0138  *
0139  * regs_get_register returns the value of a register whose offset from @regs.
0140  * The @offset is the offset of the register in struct pt_regs.
0141  * If @offset is bigger than MAX_REG_OFFSET, this returns 0.
0142  */
0143 static inline unsigned long regs_get_register(struct pt_regs *regs,
0144                           unsigned int offset)
0145 {
0146     if (unlikely(offset > MAX_REG_OFFSET))
0147         return 0;
0148     return *(unsigned long *)((unsigned long)regs + offset);
0149 }
0150 
0151 /* Valid only for Kernel mode traps. */
0152 static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
0153 {
0154     return regs->ARM_sp;
0155 }
0156 
0157 static inline unsigned long user_stack_pointer(struct pt_regs *regs)
0158 {
0159     return regs->ARM_sp;
0160 }
0161 
0162 #define current_pt_regs(void) ({ (struct pt_regs *)         \
0163         ((current_stack_pointer | (THREAD_SIZE - 1)) - 7) - 1;  \
0164 })
0165 
0166 
0167 /*
0168  * Update ITSTATE after normal execution of an IT block instruction.
0169  *
0170  * The 8 IT state bits are split into two parts in CPSR:
0171  *  ITSTATE<1:0> are in CPSR<26:25>
0172  *  ITSTATE<7:2> are in CPSR<15:10>
0173  */
0174 static inline unsigned long it_advance(unsigned long cpsr)
0175 {
0176     if ((cpsr & 0x06000400) == 0) {
0177         /* ITSTATE<2:0> == 0 means end of IT block, so clear IT state */
0178         cpsr &= ~PSR_IT_MASK;
0179     } else {
0180         /* We need to shift left ITSTATE<4:0> */
0181         const unsigned long mask = 0x06001c00;  /* Mask ITSTATE<4:0> */
0182         unsigned long it = cpsr & mask;
0183         it <<= 1;
0184         it |= it >> (27 - 10);  /* Carry ITSTATE<2> to correct place */
0185         it &= mask;
0186         cpsr &= ~mask;
0187         cpsr |= it;
0188     }
0189     return cpsr;
0190 }
0191 
0192 #endif /* __ASSEMBLY__ */
0193 #endif