linux struct pt_regs结构体

本文详细解释了Linux内核中针对arm32和arm64架构的structpt_regs结构体定义,包括其各个寄存器的偏移量,以及structuser_pt_regs的用途,强调了栈在异常处理中的作用和对结构体大小的要求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文基于linux-4.19.125

arm32

struct pt_regs结构体定义

struct pt_regs结构体定义位于arch/arm/include/asm/ptrace.h 文件:

struct pt_regs {
	unsigned long uregs[18];
};

struct svc_pt_regs {
	struct pt_regs regs;
	u32 dacr;
	u32 addr_limit;
};

pt_regs结构体含义 

关于pt_regs结构体的含义,可在编译生成的include/generated/asm-offsets.h中查到:

#define S_R0 0 /* offsetof(struct pt_regs, ARM_r0) */
#define S_R1 4 /* offsetof(struct pt_regs, ARM_r1) */
#define S_R2 8 /* offsetof(struct pt_regs, ARM_r2) */
#define S_R3 12 /* offsetof(struct pt_regs, ARM_r3) */
#define S_R4 16 /* offsetof(struct pt_regs, ARM_r4) */
#define S_R5 20 /* offsetof(struct pt_regs, ARM_r5) */
#define S_R6 24 /* offsetof(struct pt_regs, ARM_r6) */
#define S_R7 28 /* offsetof(struct pt_regs, ARM_r7) */
#define S_R8 32 /* offsetof(struct pt_regs, ARM_r8) */
#define S_R9 36 /* offsetof(struct pt_regs, ARM_r9) */
#define S_R10 40 /* offsetof(struct pt_regs, ARM_r10) */
#define S_FP 44 /* offsetof(struct pt_regs, ARM_fp) */
#define S_IP 48 /* offsetof(struct pt_regs, ARM_ip) */
#define S_SP 52 /* offsetof(struct pt_regs, ARM_sp) */
#define S_LR 56 /* offsetof(struct pt_regs, ARM_lr) */
#define S_PC 60 /* offsetof(struct pt_regs, ARM_pc) */
#define S_PSR 64 /* offsetof(struct pt_regs, ARM_cpsr) */
#define S_OLD_R0 68 /* offsetof(struct pt_regs, ARM_ORIG_r0) */

或者,从arm/arm/kernel/asm-offset.c中查看:

  DEFINE(S_R0,			offsetof(struct pt_regs, ARM_r0));
  DEFINE(S_R1,			offsetof(struct pt_regs, ARM_r1));
  DEFINE(S_R2,			offsetof(struct pt_regs, ARM_r2));
  DEFINE(S_R3,			offsetof(struct pt_regs, ARM_r3));
  DEFINE(S_R4,			offsetof(struct pt_regs, ARM_r4));
  DEFINE(S_R5,			offsetof(struct pt_regs, ARM_r5));
  DEFINE(S_R6,			offsetof(struct pt_regs, ARM_r6));
  DEFINE(S_R7,			offsetof(struct pt_regs, ARM_r7));
  DEFINE(S_R8,			offsetof(struct pt_regs, ARM_r8));
  DEFINE(S_R9,			offsetof(struct pt_regs, ARM_r9));
  DEFINE(S_R10,			offsetof(struct pt_regs, ARM_r10));
  DEFINE(S_FP,			offsetof(struct pt_regs, ARM_fp));
  DEFINE(S_IP,			offsetof(struct pt_regs, ARM_ip));
  DEFINE(S_SP,			offsetof(struct pt_regs, ARM_sp));
  DEFINE(S_LR,			offsetof(struct pt_regs, ARM_lr));
  DEFINE(S_PC,			offsetof(struct pt_regs, ARM_pc));
  DEFINE(S_PSR,			offsetof(struct pt_regs, ARM_cpsr));
  DEFINE(S_OLD_R0,		offsetof(struct pt_regs, ARM_ORIG_r0));
  DEFINE(PT_REGS_SIZE,		sizeof(struct pt_regs));

arm64

pt_regs结构体定义

在arch/arm64/include/asm/ptrace.h文件中定义了struct pt_regs结构体:

/*
 * This struct defines the way the registers are stored on the stack during an
 * exception. Note that sizeof(struct pt_regs) has to be a multiple of 16 (for
 * stack alignment). 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;
#ifdef __AARCH64EB__
	u32 unused2;
	s32 syscallno;
#else
	s32 syscallno;
	u32 unused2;
#endif

	u64 orig_addr_limit;
	u64 unused;	// maintain 16 byte alignment
	u64 stackframe[2];
};

其中struct user_pt_regs的定义位于arch/arm64/include/uapi/asm/ptrace.h :

/*
 * User structures for general purpose, floating point and debug registers.
 */
struct user_pt_regs {
	__u64		regs[31];
	__u64		sp;
	__u64		pc;
	__u64		pstate;
};

pt_regs结构体含义

关于pt_regs结构体的含义,可在编译生成的include/generated/asm-offsets.h中查到:

#define S_X0 0 /* offsetof(struct pt_regs, regs[0]) */
#define S_X1 8 /* offsetof(struct pt_regs, regs[1]) */
#define S_X2 16 /* offsetof(struct pt_regs, regs[2]) */
#define S_X3 24 /* offsetof(struct pt_regs, regs[3]) */
#define S_X4 32 /* offsetof(struct pt_regs, regs[4]) */
#define S_X5 40 /* offsetof(struct pt_regs, regs[5]) */
#define S_X6 48 /* offsetof(struct pt_regs, regs[6]) */
#define S_X7 56 /* offsetof(struct pt_regs, regs[7]) */
#define S_X8 64 /* offsetof(struct pt_regs, regs[8]) */
#define S_X10 80 /* offsetof(struct pt_regs, regs[10]) */
#define S_X12 96 /* offsetof(struct pt_regs, regs[12]) */
#define S_X14 112 /* offsetof(struct pt_regs, regs[14]) */
#define S_X16 128 /* offsetof(struct pt_regs, regs[16]) */
#define S_X18 144 /* offsetof(struct pt_regs, regs[18]) */
#define S_X20 160 /* offsetof(struct pt_regs, regs[20]) */
#define S_X22 176 /* offsetof(struct pt_regs, regs[22]) */
#define S_X24 192 /* offsetof(struct pt_regs, regs[24]) */
#define S_X26 208 /* offsetof(struct pt_regs, regs[26]) */
#define S_X28 224 /* offsetof(struct pt_regs, regs[28]) */
#define S_LR 240 /* offsetof(struct pt_regs, regs[30]) */
#define S_SP 248 /* offsetof(struct pt_regs, sp) */
#define S_PSTATE 264 /* offsetof(struct pt_regs, pstate) */
#define S_PC 256 /* offsetof(struct pt_regs, pc) */
#define S_ORIG_X0 272 /* offsetof(struct pt_regs, orig_x0) */
#define S_SYSCALLNO 280 /* offsetof(struct pt_regs, syscallno) */
#define S_ORIG_ADDR_LIMIT 288 /* offsetof(struct pt_regs, orig_addr_limit) */
#define S_STACKFRAME 304 /* offsetof(struct pt_regs, stackframe) */
#define S_FRAME_SIZE 320 /* sizeof(struct pt_regs) */

或者,从arm/arm64/kernel/asm-offset.c中查看:

  DEFINE(S_X0,			offsetof(struct pt_regs, regs[0]));
  DEFINE(S_X1,			offsetof(struct pt_regs, regs[1]));
  DEFINE(S_X2,			offsetof(struct pt_regs, regs[2]));
  DEFINE(S_X3,			offsetof(struct pt_regs, regs[3]));
  DEFINE(S_X4,			offsetof(struct pt_regs, regs[4]));
  DEFINE(S_X5,			offsetof(struct pt_regs, regs[5]));
  DEFINE(S_X6,			offsetof(struct pt_regs, regs[6]));
  DEFINE(S_X7,			offsetof(struct pt_regs, regs[7]));
  DEFINE(S_X8,			offsetof(struct pt_regs, regs[8]));
  DEFINE(S_X10,			offsetof(struct pt_regs, regs[10]));
  DEFINE(S_X12,			offsetof(struct pt_regs, regs[12]));
  DEFINE(S_X14,			offsetof(struct pt_regs, regs[14]));
  DEFINE(S_X16,			offsetof(struct pt_regs, regs[16]));
  DEFINE(S_X18,			offsetof(struct pt_regs, regs[18]));
  DEFINE(S_X20,			offsetof(struct pt_regs, regs[20]));
  DEFINE(S_X22,			offsetof(struct pt_regs, regs[22]));
  DEFINE(S_X24,			offsetof(struct pt_regs, regs[24]));
  DEFINE(S_X26,			offsetof(struct pt_regs, regs[26]));
  DEFINE(S_X28,			offsetof(struct pt_regs, regs[28]));
  DEFINE(S_LR,			offsetof(struct pt_regs, regs[30]));
  DEFINE(S_SP,			offsetof(struct pt_regs, sp));
#ifdef CONFIG_COMPAT
  DEFINE(S_COMPAT_SP,		offsetof(struct pt_regs, compat_sp));
#endif
  DEFINE(S_PSTATE,		offsetof(struct pt_regs, pstate));
  DEFINE(S_PC,			offsetof(struct pt_regs, pc));
  DEFINE(S_ORIG_X0,		offsetof(struct pt_regs, orig_x0));
  DEFINE(S_SYSCALLNO,		offsetof(struct pt_regs, syscallno));
  DEFINE(S_ORIG_ADDR_LIMIT,	offsetof(struct pt_regs, orig_addr_limit));
  DEFINE(S_STACKFRAME,		offsetof(struct pt_regs, stackframe));
  DEFINE(S_FRAME_SIZE,		sizeof(struct pt_regs));

root@localhost:~/5.15-13# tools/bazel run //common:kernel_aarch64_dist --config=fast INFO: Analyzed target //common:kernel_aarch64_dist (0 packages loaded, 0 targets configured). INFO: Found 1 target... ERROR: /root/5.15-13/common/BUILD.bazel:52:22: Building kernel kernel_aarch64 failed: (Exit 2): bash failed: error executing command (from target //common:kernel_aarch64) /bin/bash -c ... (remaining 1 argument skipped) /root/5.15-13/common/kernel/sys.c:3078:29: error: no member named 'fp_regs' in 'struct reg_data' memcpy(&g_reg_data->fp_regs, &fp, sizeof(struct user_fpsimd_state)); ~~~~~~~~~~ ^ /root/5.15-13/common/kernel/sys.c:3100:11: error: assigning to 'struct perf_event *' from incompatible type 'typeof (*(*bp_ptr))' (aka 'struct perf_event'); remove * cpu_event = *this_cpu_ptr(*bp_ptr); ^ ~~~~~~~~~~~~~~~~~~~~~~ /root/5.15-13/common/kernel/sys.c:3125:8: error: incompatible pointer types assigning to 'struct perf_event *' from 'struct perf_event **'; dereference with * [-Werror,-Wincompatible-pointer-types] new_bp = register_wide_hw_breakpoint(&new_attr, hwbp_handler, current); ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * /root/5.15-13/common/kernel/sys.c:3132:31: error: incompatible pointer types passing 'struct perf_event *' to parameter of type 'struct perf_event **'; remove * [-Werror,-Wincompatible-pointer-types] unregister_wide_hw_breakpoint(*bp_ptr); ^~~~~~~ /root/5.15-13/common/include/linux/hw_breakpoint.h:76:73: note: passing argument to parameter 'cpu_events' here extern void unregister_wide_hw_breakpoint(struct perf_event * __percpu *cpu_events); ^ /root/5.15-13/common/kernel/sys.c:3138:18: error: assigning to 'struct perf_event *' from incompatible type 'typeof (*(new_bp))' (aka 'struct perf_event'); remove * info->sample_hbp = *this_cpu_ptr(new_bp); ^ ~~~~~~~~~~~~~~~~~~~~~ /root/5.15-13/common/kernel/sys.c:3159:11: error: no member named 'b极_addr' in 'struct perf_event_attr'; did you mean 'bp_addr'? orig_attr.b极_addr = info->original_addr; ^~~~~~~~ bp_addr /root/5.15-13/common/include/uapi/linux/perf_event.h:423:10: note: 'bp_addr' declared here __u64 bp_addr; ^ /root/5.15-13/common/kernel/sys.c:3162:9: error: incompatible pointer types assigning to 'struct perf_event *' from 'struct perf_event **'; dereference with * [-Werror,-Wincompatible-pointer-types] orig_bp = register_wide_hw_breakpoint(&orig_attr, hwbp_handler, current); ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * /root/5.15-13/common/kernel/sys.c:3169:31: error: incompatible pointer types passing 'struct perf_event *' to parameter of type 'struct perf_event **'; remove * [-Werror,-Wincompatible-pointer-types] unregister_wide_hw_breakpoint(*bp_ptr); ^~~~~~~ /root/5.15-13/common/include/linux/hw_breakpoint.h:76:73: note: passing argument to parameter 'cpu_events' here extern void unregister_wide_hw_breakpoint(struct perf_event * __percpu *cpu_events); ^ /root/5.15-13/common/kernel/sys.c:3175:18: error: assigning to 'struct perf_event *' from incompatible type 'typeof (*(orig_bp))' (aka 'struct perf_event'); remove * info->sample_hbp = *this_cpu_ptr(orig_bp); ^ ~~~~~~~~~~~~~~~~~~~~~~ /root/5.15-13/common/kernel/sys.c:3334:31: error: incompatible pointer types passing 'struct perf_event *' to parameter of type 'struct perf_event **'; take the address with & [-Werror,-Wincompatible-pointer-types] unregister_wide_hw_breakpoint(bp); ^~ & /root/5.15-13/common/include/linux/hw_breakpoint.h:76:73: note: passing argument to parameter 'cpu_events' here extern void unregister_wide_hw_breakpoint(struct perf_event * __percpu *cpu_events); ^ /root/5.15-13/common/kernel/sys.c:3423:31: error: incompatible pointer types passing 'struct perf_event *' to parameter of type 'struct perf_event **'; take the address with & [-Werror,-Wincompatible-pointer-types] unregister_wide_hw_breakpoint(bp); ^~ & /root/5.15-13/common/include/linux/hw_breakpoint.h:76:73: note: passing argument to parameter 'cpu_events' here extern void unregister_wide_hw_breakpoint(struct perf_event * __percpu *cpu_events); ^ /root/5.15-13/common/kernel/sys.c:3499:4: error: incompatible pointer types assigning to 'struct perf_event *' from 'struct perf_event **'; dereference with * [-Werror,-Wincompatible-pointer-types] bp = register_wide_hw_breakpoint(&attr, hwbp_handler, tsk); ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * /root/5.15-13/common/kernel/sys.c:3507:22: error: assigning to 'struct perf_event *' from incompatible type 'typeof (*(bp))' (aka 'struct perf_event'); remove * new_info->sample_hbp = *this_cpu_ptr(bp); // 关联断点句柄 ^ ~~~~~~~~~~~~~~~~~ 13 errors generated. make[2]: *** [/root/5.15-13/common/scripts/Makefile.build:287: kernel/sys.o] Error 1 make[1]: *** [/root/5.15-13/common/Makefile:1953: kernel] Error 2 make: *** [Makefile:244: __sub-make] Error 2 [6 / 14] 2 actions running Preparing for module build //common:kernel_aarch64_modules_prepare; 14s linux-sandbox Building UAPI kernel headers kernel_aarch64_uapi_headers; 14s linux-sandbox 仔细阅读linux文档 在仔细阅读报错原因 完整修复好发给我
最新发布
07-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值