как сохранить содержимое регистра GS
От: assad Россия  
Дата: 07.10.04 08:36
Оценка:
В моей программе, используется некая библиотека.
Эта библиотека использует регистр gs. причем gs она сама устанавливает равным 7.
Я создаю ldt c одной записью, затем библиотека заносит в gs 7.
во время выполнения программы gs сбрасывается в 0.
с помощью softice установил, что в tss gs = 0.
Скорее всего gs сбрасывается при переключении задач.

Вопрос. Как сделать так, чтобы при переключении задач gs не сбрасывался.
Может можно как-то дать указание sheduler'у перед переключением контекста задачи сохранить содержимое этого регистра?

Инициализация ldt, модификация и использования gs происходят в user mode.
ldt точно создаётся. если отлавливать page fault в __try ... __except,
а затем выставлять gs в нужную величину то вроде всё работает.
Но это как-то некрасиво, т.е. заранее ведь неизвестно gs будет 7 или нет в другой системе может уже существовать 0 запись в ldt.
системы winNT/2k/XP. в худшем случае хватит и win2k/XP.
Re: как сохранить содержимое регистра GS
От: Murr Россия  
Дата: 10.10.04 17:13
Оценка:
Здравствуйте, assad, Вы писали:

A>В моей программе, используется некая библиотека.

A>Эта библиотека использует регистр gs. причем gs она сама устанавливает равным 7.
A>Я создаю ldt c одной записью, затем библиотека заносит в gs 7.
A>во время выполнения программы gs сбрасывается в 0.
A>с помощью softice установил, что в tss gs = 0.
A>Скорее всего gs сбрасывается при переключении задач.

А разве в Win нити переключаются через TSS?
Вряд ли Win — настолько корявая поделка индусов, что там про gs забыли.
Может gs неявно изменяется кодом вашей программы?
Re[2]: как сохранить содержимое регистра GS
От: Ivan Korotkov Россия  
Дата: 10.10.04 17:54
Оценка:
Здравствуйте, Murr, Вы писали:

A>>В моей программе, используется некая библиотека.

A>>Эта библиотека использует регистр gs. причем gs она сама устанавливает равным 7.
A>>Я создаю ldt c одной записью, затем библиотека заносит в gs 7.
A>>во время выполнения программы gs сбрасывается в 0.
A>>с помощью softice установил, что в tss gs = 0.
A>>Скорее всего gs сбрасывается при переключении задач.

M>А разве в Win нити переключаются через TSS?

M>Вряд ли Win — настолько корявая поделка индусов, что там про gs забыли.
M>Может gs неявно изменяется кодом вашей программы?

TSS тут не при чем. Просто где-то в ядре gs, похоже используется, а при переключении на более низкий уровень привилегий, все сег. регистры, указывающие на более привилегированные сегменты, проц обнуляет. Поэтому при возврате из любого системного вызова gs=0. Обойти это можно, наверное, только пропатчив ядро.
--
Ivan
Re[3]: как сохранить содержимое регистра GS
От: assad Россия  
Дата: 12.10.04 14:28
Оценка:
Здравствуйте, Ivan Korotkov, Вы писали:

IK>TSS тут не при чем. Просто где-то в ядре gs, похоже используется, а при переключении на более низкий уровень привилегий, все сег. регистры, указывающие на более привилегированные сегменты, проц обнуляет. Поэтому при возврате из любого системного вызова gs=0. Обойти это можно, наверное, только пропатчив ядро.


Спасибо за ответ!
Возникает ещё один. как можно обойтись без того чтобы патчить. драйвер бы пошёл. но что это должен быть за драйвер? хоть на что обратить внимание.
Пока думаю изучить логику работы ntvdm, т.к. этот сервис для dos программ-то должен сохранять gs.

ЗЫ:
насоздавал потоков и теперь gs при переключении потоков gs может быть равно gs из другого потока.
Re[3]: как сохранить содержимое регистра GS
От: Murr Россия  
Дата: 13.10.04 12:17
Оценка:
Здравствуйте, Ivan Korotkov, Вы писали:


IK>TSS тут не при чем. Просто где-то в ядре gs, похоже используется, а при переключении на более низкий уровень привилегий, все сег. регистры, указывающие на более привилегированные сегменты, проц обнуляет. Поэтому при возврате из любого системного вызова gs=0. Обойти это можно, наверное, только пропатчив ядро.



А разве автор использует привилегированные сегменты?

То, что ядро использует какие-то регистры — это его (ядра) личное дело,
но перед возвратом их надо бы восстанавливать(кроме статуса возврата).

Если этого не происходит, то это и есть криворукость.
Re[4]: как сохранить содержимое регистра GS
От: Ivan Korotkov Россия  
Дата: 13.10.04 15:37
Оценка:
Здравствуйте, Murr, Вы писали:

M>А разве автор использует привилегированные сегменты?


Нет. А кто говорил об авторе?

M>То, что ядро использует какие-то регистры — это его (ядра) личное дело,

M>но перед возвратом их надо бы восстанавливать(кроме статуса возврата).

M>Если этого не происходит, то это и есть криворукость.


Никакой криворукости тут нет. Это одно из соглашений винды — gs после любого системного вызова всегда есть 0, точно так же как соглашение по возврату значения в eax или по сохранению esi/edi/ebx.
--
Ivan
Re[5]: как сохранить содержимое регистра GS
От: Murr Россия  
Дата: 14.10.04 07:30
Оценка:
Здравствуйте, Ivan Korotkov, Вы писали:

IK>Нет. А кто говорил об авторе?


Это вообще-то его тема. =)

IK>Никакой криворукости тут нет. Это одно из соглашений винды — gs после любого системного вызова всегда есть 0, точно так же как соглашение по возврату значения в eax или по сохранению esi/edi/ebx.


Ну насчет системных вызовов — ладно, хотя и неясно зачем его в 0 сбрасывать.

А вот зачем его сбрасывать при reschedule...
Re[6]: как сохранить содержимое регистра GS
От: Ivan Korotkov Россия  
Дата: 14.10.04 15:50
Оценка:
Здравствуйте, Murr, Вы писали:

IK>>Никакой криворукости тут нет. Это одно из соглашений винды — gs после любого системного вызова всегда есть 0, точно так же как соглашение по возврату значения в eax или по сохранению esi/edi/ebx.


M>Ну насчет системных вызовов — ладно, хотя и неясно зачем его в 0 сбрасывать.


Винда его не сбрасывает. Винде просто лень его сохранять, чтобы меньше тормозило. А сбрасывает сам проц.

M>А вот зачем его сбрасывать при reschedule...


Пардон, поправлюсь — после любой (не)явной передачи управления ядру.
--
Ivan
Re[2]: как сохранить содержимое регистра GS
От: assad Россия  
Дата: 15.10.04 06:24
Оценка: 1 (1)
A>>Скорее всего gs сбрасывается при переключении задач.
Беру свои слова назад. всё таки sheduler gs не портит.

Как выяснилось его портит любой системный вызов и любой обработчик исключений seh.

Но в EXCEPTION_RECORDS в context лежит не 0, т.е. старый gs.

Отсюда решение: перед windows syscall сохраняем gs, в исключении eip перенастраиваем на свой handler которому в качестве параметров передаются всё нужные регистры, в том числе и gs.
Благо, архитектура приложения позволяет легко сделать такой финт практически без потерь производительности и с минимальными исправлениями...

Спасибо всем откликнувшимся!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.