Page 1 of 2

AT&T syntax

Posted: Tue Aug 30, 2005 11:33 am
by DruG5t0r3
I'm moving my code to AT&T...(arghhh) and there is a few things I might need help for...

first thing is I'm trying to do a far call to a ring 3 code segment from ring 0.

Something like call 0x08:offset in intel syntax.

What would it be in AT&T?

Re:AT&T syntax

Posted: Tue Aug 30, 2005 12:03 pm
by Guest
I believe something along the lines of:

Code: Select all

lcall $0x08, $offset

Re:AT&T syntax

Posted: Tue Aug 30, 2005 12:45 pm
by DruG5t0r3
Okay...I'm just about to run crazy here...

I'm trying to ljmp to some ring 3 code from ring 0 code.
with something like this

__asm__ ("ljmp $0x1b, $ring_3_code");

0x1b is actually 0x18 + 3 for the RPL, Is that right?

I get a General Protection Fault, it doesn't actually even jmp to that code.

If I change this value from 0x1b to 0x08 which is my ring 0 code segment. Well everything is fine.

Re:AT&T syntax

Posted: Tue Aug 30, 2005 5:15 pm
by Simon
If 0x18 is your user mode code segment then yes,you need to add 3. It might be that you can't switch priviledge levels without using a TSS or 'iret'ing to the code,that's the only explanation I can think of as those are the only ways to load SS at the same time.

Re:AT&T syntax

Posted: Wed Aug 31, 2005 9:04 am
by DruG5t0r3
I do have a TSS, but there is no SS and ESP for ring 3 code in it right? Only for privilege levels < 3.

I thought that the only time you'd need the TSS for is when you switched form level 3 code to anything lower.

Re:AT&T syntax

Posted: Wed Aug 31, 2005 1:01 pm
by DruG5t0r3
Help anyone? I'm really stuck on this one.

Thanks.

Re:AT&T syntax

Posted: Wed Aug 31, 2005 2:32 pm
by DruG5t0r3
Here is my source code, keep in mind i'm simply trying to switch to ring 3 code

Code: Select all

void gdt_set_gate(int num, unsigned long base, unsigned long limit, 
unsigned char access, unsigned char gran)
{
   memset(&gdt[num], 0, sizeof(struct gdtr));

   gdt[num].base_low = (base & 0xFFFF);
   gdt[num].base_middle = (base >> 16) & 0xFF;
   gdt[num].base_high = (base >> 24) & 0xFF;
 
   gdt[num].limit_low = (limit & 0xFFFF);
   gdt[num].gran = ((limit >> 16) & 0x0F);

   gdt[num].gran |= (gran & 0xF0);
       gdt[num].access = access;
}

// Main gdt.c function called from kernel.c
// Will install all the global descriptor tables and the Task-State Segment.
void gdt_install()
{
   unsigned short tss_val;

       gdt_set_gate(NULL_SEG, 0, 0, 0, 0);

       // Code Descriptor, 4gb limit, 0 base
       gdt_set_gate(CODE0_SEG, 0, 0xFFFFFFFF, 0x9A, 0xCF);

       // Same thing for data segment.
       gdt_set_gate(DATA0_SEG, 0, 0xFFFFFFFF, 0x92, 0xCF);
   
   // base ring 3 code segment
   gdt_set_gate(CODE3_SEG, 0, 0xFFFFFFFF, 0xFA, 0xCF);

   // base ring 3 data segment
   gdt_set_gate(DATA3_SEG, 0, 0xFFFFFFFF, 0xF2, 0xCF);

   // Main TSS Descriptor
   gdt_set_gate(TSS_SEG, (unsigned long)&kernel_tss, 0x67, 0xE9, 0x80);
Now this is my "test code"

Code: Select all

void ring3_code() {
   for(;;);
}

void switch_to() {

   __asm__ __volatile__ ("ljmp $0x1b,$ring3_code");
}
If I change 0x1b to 0x08 which is my code 0 ring segment , NOOo problem. But with the above, General Protection Fault. Hellpp

Re:AT&T syntax

Posted: Wed Aug 31, 2005 6:43 pm
by AR
Without a TSS the system will explode when it tries to load SS0 when an interrupt occurs in Ring 3. The obvious problem there is that your task is C code and therefore probably disassembles as:

Code: Select all

push %ebp
mov %esp, %ebp

1:
jmp 1b

pop %ebp
ret
The push at the start attempts to write to the stack which is still Ring0 (DPL < CPL) which will throw a GPF. If this is actually the case then you will need to load the Ring3 stack before switching or write the task in assembly.

Re:AT&T syntax

Posted: Wed Aug 31, 2005 6:47 pm
by DruG5t0r3
nah, it GP faults when executing the jmp, it doesnt actually jmp.

and the IF flag is cleared anyway

Re:AT&T syntax

Posted: Wed Aug 31, 2005 7:29 pm
by AR
The only other thing that comes to mind is that you aren't allowed to jump/call DPL/RPL > CPL, I don't think this is the case (I don't have the docs with me) but you may want to try using IRET to switch anyway.

Re:AT&T syntax

Posted: Wed Aug 31, 2005 7:47 pm
by DruG5t0r3
I have tried the IRET equivalent and it does the same error.

I have found something in the Intel Manual Though...and it reads
Execution cannot be transferred by a call or a jump to a less-privilged (nummerically higher privilege level) code segment, regardless of whether the target segment is a conforming or nonconforming code segment. Attempting such an execution will result in a general-protection exception.
Interesting...sounds like you can't jmp from more priviledged segment to a less one. I thought it was possible, at least logicaly possible, but, as always, the specs aren't always what you think they should be.

So in the end, what would be the only way to switch over? Through a call gate?

Re:AT&T syntax

Posted: Wed Aug 31, 2005 11:39 pm
by Brendan
Hi,
DruG5t0r3 wrote:So in the end, what would be the only way to switch over? Through a call gate?
Pretend to do a return from an interrupt (IRET) or a return from a call gate (RETF).

Why didn't "IRET" work?


Cheers,

Brendan

Re:AT&T syntax

Posted: Thu Sep 01, 2005 5:28 am
by DruG5t0r3
Exact same error

Code: Select all

void ring3_code() {
   for(;;);
}

void switch_to() {

   __asm__ __volatile__ ("pushfl; \
            pushl $0x1b; \
            pushl %0; \
            iret"::"r"((unsigned int)ring3_code));
}
But if I change the $0x1b value to 0x08, again it works.
As I said, with $0x1b, it doesn't actually even jump, it GP faults while executing the iret.

Re:AT&T syntax

Posted: Thu Sep 01, 2005 6:24 am
by Brendan
Hi,
DruG5t0r3 wrote: Exact same error

Code: Select all

   __asm__ __volatile__ ("pushfl; \
            pushl $0x1b; \
            pushl %0; \
            iret"::"r"((unsigned int)ring3_code));
A slightly different error, with the same exception!

For an interrupt, the CPU pops EIP, then CS, then EFLAGS, so for your code what does it pop for EFLAGS?


Cheers,

Brendan

Re:AT&T syntax

Posted: Thu Sep 01, 2005 6:34 am
by DruG5t0r3
"pushfl"

Doesn't that push the EFLAGS?