PTRACE_PEEKUSER
この領域で単語を読むことが文書化されており、user
x86_64の部分レイアウトは次のとおりです。
struct user
{
struct user_regs_struct regs;
int u_fpvalid;
struct user_fpregs_struct i387;
//...
int u_debugreg [8];
};
内部または内部オフセットを使用して幸せにPTRACE_PEEKUSER
呼び出すことはできますが、内部オフセットを渡すと無条件に返されます。regs
u_debugreg
i387
EIO
カーネルのコードを見ると、内部で読み取ったregs
合計がu_debugreg
唯一サポートされているオフセットであることがわかります。
case PTRACE_PEEKUSR: {
unsigned long tmp;
ret = -EIO;
if ((addr & (sizeof(data) - 1)) || addr >= sizeof(struct user))
break;
tmp = 0; /* Default return condition */
if (addr < sizeof(struct user_regs_struct))
tmp = getreg(child, addr);
else if (addr >= offsetof(struct user, u_debugreg[0]) &&
addr <= offsetof(struct user, u_debugreg[7])) {
addr -= offsetof(struct user, u_debugreg[0]);
tmp = ptrace_get_debugreg(child, addr / sizeof(data));
}
ret = put_user(tmp, datap);
break;
}
読み取りをサポートしていないことがわかりますi387
。私は呼び出してこのレジスタを読むことができることを知っていますPTRACE_GETFPREGS
。私の質問は:PTRACE_PEEKUSER
これらのレジスタを使用して書き込めない特別な理由はありますか?PTRACE_POKEUSER
私の推測では、ほとんどのフィールドはuser_fpregs_struct
64ビット未満であるため、読み取りと書き込みは複数のレジスタを扱う可能性があるためです。しかし、私は公開ソースを作成し、それに注釈を付けるので、私の推測が正しいことを確認したいと思います。
答え1
推測してみてください。数学補助プロセッサレジスタを読みたいです。i387
カーネルのメンバーがいつ更新されるのか確認しましたか?struct user
私はそうではなく、間違っているかもしれませんが、私の推測は一般的ではありませんが、コアダンプのような場合はそうです。
Arch/x86/include/asm/user_64.hから
struct user {
/* We start with the registers, to mimic the way that "memory" is returned
from the ptrace(3,...) function. */
struct user_regs_struct regs; /* Where the registers are actually stored */
/* ptrace does not yet supply these. Someday.... */
int u_fpvalid; /* True if math co-processor being used. */
/* for this mess. Not yet used. */
int pad0;
struct user_i387_struct i387; /* Math Co-processor registers. */
:
unsigned long u_debugreg[8];
:
};
したがって、数学補助プロセッサ・レジスタの読み出しは、FPUから読み出すのが最善です。カーネルがどのように実行されているかを確認すると、PTRACE_GETFPREGS
メンバーではなくFPUからインポートされていることがわかりますstruct user
i387
。補助プロセッサレジスタを使用して数学を書く場合も同様ですPTRACE_SETFPREGS
。
~からarch_ptrace
case PTRACE_GETFPREGS: /* Get the child FPU state. */
return copy_regset_to_user(child,
task_user_regset_view(current),
REGSET_FP,
0, sizeof(struct user_i387_struct),
datap);
task_user_regset_view
x86_64_regsets
読み取りの戻り値ですxfpregs_get
。
static struct user_regset x86_64_regsets[] __ro_after_init = {
[REGSET_FP] = {
.core_note_type = NT_PRFPREG,
.n = sizeof(struct user_i387_struct) / sizeof(long),
.size = sizeof(long), .align = sizeof(long),
.active = regset_xregset_fpregs_active, .regset_get = xfpregs_get, .set = xfpregs_set
},
}
const struct user_regset_view *task_user_regset_view(struct task_struct *task)
{
:
#ifdef CONFIG_X86_64
return &user_x86_64_view;
#endif
}