Я делаю некоторое экспериментирование и хотел бы смочь видеть то, что сохраняется на стеке во время системного вызова (сохраненное состояние процесса пространства пользователя). Согласно http://lxr.linux.no/#linux+v2.6.30.1/arch/x86/kernel/entry_32.S это показывает, что различные значения регистров сохраняются при тех конкретных смещениях к указателю вершины стека. Вот код, который я пытался использовать для исследования то, что сохраняется на стеке (это находится в пользовательском системном вызове, который я создал):
asm("movl 0x1C(%esp), %ecx");
asm("movl %%ecx, %0" : "=r" (value));
где значение является неподписанным долго.
С прямо сейчас, это значение не то, что ожидается (оно показывает, что 0 сохраняется для пользовательского значения ds).
Я правильно получаю доступ к смещению указателя вершины стека?
Другая возможность могла бы быть, я мог использовать отладчик, такой как GDB для исследования содержания стека в то время как в ядре? У меня нет большого широкого применения с отладкой, и не уверено в том, как отладить код в ядре. Любая справка очень ценится.
Встроенная сборка сложнее, чем кажется. Попытка кратко осветить проблемы, связанные с GCC:
Тогда ваш код станет:
asm("movl 0x1C(%%esp), %0;"
: "=r" (value)
: /* no inputs :) */
/* no modified registers */
);
Выходной аргумент не обязательно должен быть в списке clobber, потому что GCC уже знает, что он будет изменен.
В качестве альтернативы, поскольку все, что вам нужно, это значение регистра ESP, вы можете избежать всей этой боли:
register int esp asm("esp");
esp += 0x1C;
Это может не решить вашу проблему, но это правильный путь. Для справки проверьте это , this и this .
Имейте в виду, что код x86_64 часто передает значения в регистрах (поскольку их так много), поэтому в стеке ничего не будет. Проверьте промежуточный выход gcc ( -S
IIRC) и найдите в сборке push
.
Я не знаком с отладкой кода ядра, но gdb определенно лучше проверять стек в интерактивном режиме.
Нет необходимости во встроенной сборке. Сохраненное состояние, которое entry_32.S
помещает в стек для системного вызова, оформлено как struct pt_regs
, и вы можете получить указатель на нее следующим образом (вам потребуется include
и / или
прямо или косвенно):
struct pt_regs * regs = task_pt_regs (current);