/* AArch32 CPSR bits, as seen in AArch32 */ #define COMPAT_PSR_DIT_BIT 0x00200000
/* * These are 'magic' values for PTRACE_PEEKUSR that return info about where a * process is located in memory.
*/ #define COMPAT_PT_TEXT_ADDR 0x10000 #define COMPAT_PT_DATA_ADDR 0x10004 #define COMPAT_PT_TEXT_END_ADDR 0x10008
/* * If pt_regs.syscallno == NO_SYSCALL, then the thread is not executing * a syscall -- i.e., its most recent entry into the kernel from * userspace was not via SVC, or otherwise a tracer cancelled the syscall. * * This must have the value -1, for ABI compatibility with ptrace etc.
*/ #define NO_SYSCALL (-1)
if (pstate & PSR_AA32_DIT_BIT)
psr |= COMPAT_PSR_DIT_BIT;
return psr;
}
/* * This struct defines the way the registers are stored on the stack during an * exception. struct user_pt_regs must form a prefix of struct pt_regs.
*/ struct pt_regs { union { struct user_pt_regs user_regs; struct {
u64 regs[31];
u64 sp;
u64 pc;
u64 pstate;
};
};
u64 orig_x0;
s32 syscallno;
u32 pmr;
/** * regs_get_register() - get register value from its offset * @regs: pt_regs from which register value is gotten * @offset: offset of the register. * * regs_get_register returns the value of a register whose offset from @regs. * The @offset is the offset of the register in struct pt_regs. * If @offset is bigger than MAX_REG_OFFSET, this returns 0.
*/ staticinline u64 regs_get_register(struct pt_regs *regs, unsignedint offset)
{
u64 val = 0;
WARN_ON(offset & 7);
offset >>= 3; switch (offset) { case 0 ... 30:
val = regs->regs[offset]; break; case offsetof(struct pt_regs, sp) >> 3:
val = regs->sp; break; case offsetof(struct pt_regs, pc) >> 3:
val = regs->pc; break; case offsetof(struct pt_regs, pstate) >> 3:
val = regs->pstate; break; default:
val = 0;
}
return val;
}
/* * Read a register given an architectural register index r. * This handles the common case where 31 means XZR, not SP.
*/ staticinlineunsignedlong pt_regs_read_reg(conststruct pt_regs *regs, int r)
{ return (r == 31) ? 0 : regs->regs[r];
}
/* * Write a register given an architectural register index r. * This handles the common case where 31 means XZR, not SP.
*/ staticinlinevoid pt_regs_write_reg(struct pt_regs *regs, int r, unsignedlong val)
{ if (r != 31)
regs->regs[r] = val;
}
/* Valid only for Kernel mode traps. */ staticinlineunsignedlong kernel_stack_pointer(struct pt_regs *regs)
{ return regs->sp;
}
staticinlineunsignedlong regs_return_value(struct pt_regs *regs)
{ unsignedlong val = regs->regs[0];
/* * Audit currently uses regs_return_value() instead of * syscall_get_return_value(). Apply the same sign-extension here until * audit is updated to use syscall_get_return_value().
*/ if (compat_user_mode(regs))
val = sign_extend64(val, 31);
/** * regs_get_kernel_argument() - get Nth function argument in kernel * @regs: pt_regs of that context * @n: function argument number (start from 0) * * regs_get_argument() returns @n th argument of the function call. * * Note that this chooses the most likely register mapping. In very rare * cases this may not return correct data, for example, if one of the * function parameters is 16 bytes or bigger. In such cases, we cannot * get access the parameter correctly and the register assignment of * subsequent parameters will be shifted.
*/ staticinlineunsignedlong regs_get_kernel_argument(struct pt_regs *regs, unsignedint n)
{ #define NR_REG_ARGUMENTS 8 if (n < NR_REG_ARGUMENTS) return pt_regs_read_reg(regs, n); return 0;
}
/* We must avoid circular header include via sched.h */ struct task_struct; int valid_user_regs(struct user_pt_regs *regs, struct task_struct *task);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.