Как проверить всдо перемен?
Я хотел бы проверить содержимое vsyscall_gtod_data (все время сохраняя связанную информацию, которая необходима для работы clock_gettime()).
Я использую GDB для пошагового выполнения кода сборки __vdso_clock_gettime(), и я смотрю на следующий раздел:
0x00007ffff7ffaa71 <clock_gettime+129>: cmp eax,DWORD PTR [rbx]
0x00007ffff7ffaa73 <clock_gettime+131>: je 0x7ffff7ffaa47 <clock_gettime+87>
0x00007ffff7ffaa75 <clock_gettime+133>: jmp 0x7ffff7ffaa56 <clock_gettime+102>
0x00007ffff7ffaa77 <clock_gettime+135>: pause
0x00007ffff7ffaa79 <clock_gettime+137>: mov r12d,DWORD PTR [rbx]
=> 0x00007ffff7ffaa7c <clock_gettime+140>: test r12b,0x1
0x00007ffff7ffaa80 <clock_gettime+144>: jne 0x7ffff7ffaa77 <clock_gettime+135>
0x00007ffff7ffaa82 <clock_gettime+146>: mov eax,DWORD PTR [rip+0xffffffffffffd5fc] # 0x7ffff7ff8084
0x00007ffff7ffaa88 <clock_gettime+152>: mov DWORD PTR [rbp-0x1c],eax
0x00007ffff7ffaa8b <clock_gettime+155>: mov rax,QWORD PTR [rip+0xffffffffffffd61e] # 0x7ffff7ff80b0
0x00007ffff7ffaa92 <clock_gettime+162>: mov QWORD PTR [rsi],rax
0x00007ffff7ffaa95 <clock_gettime+165>: mov edx,DWORD PTR [rip+0xffffffffffffd5e9] # 0x7ffff7ff8084
0x00007ffff7ffaa9b <clock_gettime+171>: mov r10,QWORD PTR [rip+0xffffffffffffd616] # 0x7ffff7ff80b8
0x00007ffff7ffaaa2 <clock_gettime+178>: cmp edx,0x1
0x00007ffff7ffaaa5 <clock_gettime+181>: je 0x7ffff7ffabc0 <clock_gettime+464>
Я считаю, что это сборка для следующего кода C (из linux-4.8.0 / arch / x86 / include / asm / vgtod.h):
static inline unsigned gtod_read_begin(const struct vsyscall_gtod_data *s)
{
unsigned ret;
repeat:
ret = ACCESS_ONCE(s->seq);
if (unlikely(ret & 1)) {
cpu_relax();
goto repeat;
}
smp_rmb();
return ret;
}
(Инструкция по сборке pause
соответствует cpu_relax()
)
Как я понимаю struct vsyscall_gtod_data *s
проводится в rbx
и адрес читается в этой инструкции:
mov r12d,DWORD PTR [rbx]
Это означает, что отлаженная программа может прочитать этот адрес, но когда я пытаюсь проверить его в gdb, я получаю сообщение об ошибке:
(gdb) x $rbx
0x7ffff7ff8080: Cannot access memory at address 0x7ffff7ff8080
(gdb)
Есть идеи о том, что происходит и как проверить эту память?
1 ответ
Я думаю, что вы пытаетесь получить доступ к области памяти, к которой можно получить доступ, только если у вас есть "уровень привилегий" 0 (уровень ОС). Не верьте мне в названии, я прочитал его пару дней назад в руководстве Intel, так что, возможно, я неправильно понял жаргон, концепция должна быть правильной.
Я не уверен на 100%, что этого будет достаточно, но пытаться не повредит. Я знаю, что некоторые регистры подсчета команд имеют схожие проблемы, и к ним можно получить доступ из пользовательского пространства, если вы sudo.