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
Reload GDT, when does changes are applied?
-
- Member
- Posts: 195
- Joined: Tue Aug 26, 2008 11:24 am
- GitHub: https://github.com/sebihepp
Re: Reload GDT, when does changes are applied?
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. =)
Course, I could be wrong. =)
Re: Reload GDT, when does changes are applied?
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.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.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
Re: Reload GDT, when does changes are applied?
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).
Re: Reload GDT, when does changes are applied?
I see--he did mention that in his first post. I just wanted to put emphases that always reloading CS is not needed.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).
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.First I thought the programm would crash, because cs:eip points now to
anywhere else.
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();}
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
Re: Reload GDT, when does changes are applied?
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).
Re: Reload GDT, when does changes are applied?
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.