2010-04-06 5 views
6

Я экспериментирую и хочу видеть, что было сохранено в стеке во время системного вызова (сохраненное состояние пользовательского сухопутного процесса). Согласно 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, для проверки содержимого стека в ядре? Я не очень много использую для отладки и не уверен, как отлаживать код внутри ядра. Буду признателен за любую оказанную помощь.

ответ

0

Имейте в виду, что код x86_64 часто передает значения в регистрах (так как их так много), поэтому ничего не будет в стеке. Проверьте промежуточный выход gcc (-S IIRC) и найдите push в сборке.

Я не знаком с отладкой кода ядра, но gdb определенно лучше изучить стек в интерактивном режиме.

4

Встроенная сборка сложнее, чем кажется. Попытка короткого рассмотрения проблем для GCC:

  1. Если он изменяет регистры процессора, необходимо поместить эти регистры в список clobber. Важно отметить, что список слюны должен содержать регистры, которые вы изменили напрямую (прямое указание )) или косвенно (неявно читать ));
  2. Для усиления (1) условные и математические операции также изменяют регистры, более известные как флаги состояния (ноль, перенос, переполнение и т. Д.), Поэтому вы должны сообщить об этом, добавив «cc» в список слюны;
  3. Добавить «память», если он изменяет разные позиции памяти (чтение случайных);
  4. Добавить ключевое слово volatile, если оно изменяет память, которая не упоминается в аргументах ввода/вывода;

Тогда ваш код становится:

asm("movl 0x1C(%%esp), %0;" 
    : "=r" (value) 
    : /* no inputs :) */ 
    /* no modified registers */ 
); 

Выходной аргумент не требуется, чтобы быть в списке затирать, потому что GCC уже знает, что он будет изменен.

С другой стороны, так как все, что вы хотите, это значение ESP регистра, вы можете избежать всех боль, делая это:

register int esp asm("esp"); 
esp += 0x1C; 

Это не может решить вашу проблему, но это путь. Для справки: this, this и this.

5

Не требуется встроенная сборка. Сохраненное состояние, что entry_32.S толкает на стек для системного вызова выложена как struct pt_regs, и вы можете получить указатель на него, как это (вам необходимо включить <asm/ptrace.h> и/или <asm/processor.h> прямо или косвенно):

struct pt_regs *regs = task_pt_regs(current);