Reload GDT, when does changes are applied?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
sebihepp
Member
Member
Posts: 195
Joined: Tue Aug 26, 2008 11:24 am
GitHub: https://github.com/sebihepp

Reload GDT, when does changes are applied?

Post by sebihepp »

Hello,

last evening I thought about reloading the GDT.
I set up a new Table and a new Descriptor and then load it via lgdt.
Let's say the Offset in the entries of the new table differs from the entries
before. There is no Problem, if the changed Entry is not in use, but...
what happens if the changed entry is currently cs for example?
First I thought the programm would crash, because cs:eip points now to
anywhere else. But then I thought, that it could be, that the changes does
only apply the next change of the registers. In my example, only when I
change cs. Am I right? Or does it really crash?

Greetings
Sebihepp
ipsemet
Posts: 14
Joined: Mon Dec 01, 2008 6:50 pm

Re: Reload GDT, when does changes are applied?

Post by ipsemet »

I'm fairly sure (though, feel free to correct me if I am wrong, anyone) that if you change the GDT in the middle of execution, you should execute a far jump immediately afterwards, in order to avoid it getting crazy results and most likely crashing.

Course, I could be wrong. =)
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: Reload GDT, when does changes are applied?

Post by neon »

I'm fairly sure (though, feel free to correct me if I am wrong, anyone) that if you change the GDT in the middle of execution, you should execute a far jump immediately afterwards, in order to avoid it getting crazy results and most likely crashing.
This only needs to be done if the selector number used for the code selector changes. Else there would be no need to reload CS.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
ipsemet
Posts: 14
Joined: Mon Dec 01, 2008 6:50 pm

Re: Reload GDT, when does changes are applied?

Post by ipsemet »

Well, I considered it to be implied that his reloading of the GDT changed the code selector (in fact, I assumed a complete change of all addresses in the GDT).
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: Reload GDT, when does changes are applied?

Post by neon »

Well, I considered it to be implied that his reloading of the GDT changed the code selector (in fact, I assumed a complete change of all addresses in the GDT).
I see--he did mention that in his first post. I just wanted to put emphases that always reloading CS is not needed.
First I thought the programm would crash, because cs:eip points now to
anywhere else.
If you just reload the GDT with CS containing a different selector the result is undefined: If CS still points to a valid selector in your new GDT that is not a code selector, it will #GPF. If it is a code selector, and eip is within gdt[cs].limit, it will still continue without error. There are other possibilities depending on the flags set for the selector that CS refers to.

Reloading the GDT does not at all change where CS:EIP points to in memory as CS does not refer to a memory address; only EIP refers to an absolute address in memory (which would not change) thus it would not crash the way you expected it to.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
quirck
Member
Member
Posts: 42
Joined: Sun Nov 23, 2008 5:56 am
Location: Russia, Saint-Petersburg

Re: Reload GDT, when does changes are applied?

Post by quirck »

Well, and what about shadow part of CS where base, limit, access rights etc. are stored? They are not changed while reloading GDT. So, CS still points to valid code segment with old base and limit. All must go right until some event occurs that changes CS (interrupt, for instance).
CodeCat
Member
Member
Posts: 158
Joined: Tue Sep 23, 2008 1:45 pm
Location: Eindhoven, Netherlands

Re: Reload GDT, when does changes are applied?

Post by CodeCat »

As far as I know, the CPU stores a cached copy of the descriptor whenever a segment register is reloaded. What this means is that as long as no segment registers are reloaded, the GDT might not need to be valid at all. You could overwrite it with zeroes and things would still work. However remember that a segment register isn't necessarily reloaded only explicitly by you - an interrupt also triggers a segment switch, so this will GPF, and then triple fault if your GDT is not valid. In general, it's best to minimise the time spent without a valid GDT.
Post Reply