Protected mode segment override problem
Posted: Tue Oct 13, 2009 5:43 pm
Hi guys,
I am implementing my syscall routines ready to use for programs. Because of the three different methods to call make syscalls (int, syscall, sysenter), i got an special page which abstracts the call for the functions (i dont call int/syscall/sysenter but call the page, just like linux does it). This works realy great when i call the address directly. But i want it to be position independent, so like linux i want to use a segment override with the gs register which points to a gdt entry with a base of the address of the syscall page.
But i tried what i could, looked everywhere but the call doesn't want work, in bochs and virtual box.
Different tries different problems:
1.
My first try was to test it from a nasm source:
gs is set to 0x33 and the gdt entry is a normal user mode code segment with the difference of the base which is 0xFEC00000.
But the given code doesn't jump to the address 0xFEC00000 but 0x55525160.
If I instead use as the call:
It works perfectly when i name the segment directly. No problems o.O
2.
My next try was to make it somehow work in gcc inline assembler
for this purpose i have this code:
Which makes just the same error and jumps to 0x55525160.
So i thought that maybe my gs register is wrong and tested this here:
and this
C0110000 is a kernel page with the syscall page.
Both make the same error and jumps to 0x55525160.
3.
So i was thinking that maybe my call is wrong and searched for another possibility and found out about lcall
so my new test code was:
But here i get a rely wried GP. It says it got a fetch_raw_descriptor on the gdt where the index is bigger then the limit.
And if i change to the cs version it gives the exact same error o.O.
So now am i stuck... and sit here thinking: where the hell is the error? Am i using the call in a wrong way? Are the emulators wrong? Or does God just hate me?
I hope someone can help me.
MfG Tarrox
I am implementing my syscall routines ready to use for programs. Because of the three different methods to call make syscalls (int, syscall, sysenter), i got an special page which abstracts the call for the functions (i dont call int/syscall/sysenter but call the page, just like linux does it). This works realy great when i call the address directly. But i want it to be position independent, so like linux i want to use a segment override with the gs register which points to a gdt entry with a base of the address of the syscall page.
But i tried what i could, looked everywhere but the call doesn't want work, in bochs and virtual box.
Different tries different problems:
1.
My first try was to test it from a nasm source:
Code: Select all
call [gs:0x0];
But the given code doesn't jump to the address 0xFEC00000 but 0x55525160.
If I instead use as the call:
Code: Select all
call 0x33:0x0
2.
My next try was to make it somehow work in gcc inline assembler
for this purpose i have this code:
Code: Select all
asm volatile ("call *%gs:0x0;");
So i thought that maybe my gs register is wrong and tested this here:
Code: Select all
asm volatile ("call *%cs:0xFEc00000;");
Code: Select all
asm volatile ("call *%cs:0c0110000;");
Both make the same error and jumps to 0x55525160.
3.
So i was thinking that maybe my call is wrong and searched for another possibility and found out about lcall
so my new test code was:
Code: Select all
asm volatile ("lcall *%gs:0x0;");
And if i change to the cs version it gives the exact same error o.O.
So now am i stuck... and sit here thinking: where the hell is the error? Am i using the call in a wrong way? Are the emulators wrong? Or does God just hate me?
I hope someone can help me.
MfG Tarrox