Protected mode segment override problem

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
tarrox
Posts: 19
Joined: Wed Dec 31, 2008 8:40 am

Protected mode segment override problem

Post by tarrox »

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:

Code: Select all

call [gs:0x0];
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:

Code: Select all

call 0x33:0x0 
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:

Code: Select all

asm volatile ("call *%gs:0x0;");
Which makes just the same error and jumps to 0x55525160.

So i thought that maybe my gs register is wrong and tested this here:

Code: Select all

asm volatile ("call *%cs:0xFEc00000;");
and this

Code: Select all

asm volatile ("call *%cs:0c0110000;");
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:

Code: Select all

asm volatile ("lcall *%gs:0x0;");
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
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Protected mode segment override problem

Post by Combuster »

tarrox wrote:My first try was to test it from a nasm source:

Code: Select all

call [gs:0x0];
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.
Did you notice that your "address" disassembles to push-push-push-push? Did you notice the memory operand in the opcode. jump to address specified in memory location gs:0. Go figure.

A far call/jump to a non-fixed location always requires that you set up an address in memory. So you should create a structure, put the segment and offset in there, and then use that as the memory operand of your far jump/call.

Also, reading the intel manuals could have answered the question, probably even faster.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
Firestryke31
Member
Member
Posts: 550
Joined: Sat Nov 29, 2008 1:07 pm
Location: Throw a dart at central Texas
Contact:

Re: Protected mode segment override problem

Post by Firestryke31 »

tarrox wrote: 1.
My first try was to test it from a nasm source:

Code: Select all

call [gs:0x0];
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.
This does not do what I think you think it does. It doesn't go to gs:0x0, it reads the address to call from gs:0x0.
Owner of Fawkes Software.
Wierd Al wrote: You think your Commodore 64 is really neato,
What kind of chip you got in there, a Dorito?
tarrox
Posts: 19
Joined: Wed Dec 31, 2008 8:40 am

Re: Protected mode segment override problem

Post by tarrox »

Firestryke31 wrote:
tarrox wrote: 1.
My first try was to test it from a nasm source:

Code: Select all

call [gs:0x0];
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.
This does not do what I think you think it does. It doesn't go to gs:0x0, it reads the address to call from gs:0x0.
Yeah after reading Combuster Post i realized that my understanding of the segment override was very very wrong. Thats why i didn't find the answer for the problem. So thanks for the help it works great^^.
Post Reply