AT&T syntax
AT&T syntax
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?
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
I believe something along the lines of:
Code: Select all
lcall $0x08, $offset
Re:AT&T syntax
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.
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
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
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.
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
Here is my source code, keep in mind i'm simply trying to switch to ring 3 code
Now this is my "test code"
If I change 0x1b to 0x08 which is my code 0 ring segment , NOOo problem. But with the above, General Protection Fault. Hellpp
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);
Code: Select all
void ring3_code() {
for(;;);
}
void switch_to() {
__asm__ __volatile__ ("ljmp $0x1b,$ring3_code");
}
Re:AT&T syntax
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: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.
Code: Select all
push %ebp
mov %esp, %ebp
1:
jmp 1b
pop %ebp
ret
Re:AT&T syntax
nah, it GP faults when executing the jmp, it doesnt actually jmp.
and the IF flag is cleared anyway
and the IF flag is cleared anyway
Re:AT&T syntax
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
I have tried the IRET equivalent and it does the same error.
I have found something in the Intel Manual Though...and it reads
So in the end, what would be the only way to switch over? Through a call gate?
I have found something in the Intel Manual Though...and it reads
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.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.
So in the end, what would be the only way to switch over? Through a call gate?
Re:AT&T syntax
Hi,
Why didn't "IRET" work?
Cheers,
Brendan
Pretend to do a return from an interrupt (IRET) or a return from a call gate (RETF).DruG5t0r3 wrote:So in the end, what would be the only way to switch over? Through a call gate?
Why didn't "IRET" work?
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re:AT&T syntax
Exact same error
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.
Code: Select all
void ring3_code() {
for(;;);
}
void switch_to() {
__asm__ __volatile__ ("pushfl; \
pushl $0x1b; \
pushl %0; \
iret"::"r"((unsigned int)ring3_code));
}
As I said, with $0x1b, it doesn't actually even jump, it GP faults while executing the iret.
Re:AT&T syntax
Hi,
For an interrupt, the CPU pops EIP, then CS, then EFLAGS, so for your code what does it pop for EFLAGS?
Cheers,
Brendan
A slightly different error, with the same exception!DruG5t0r3 wrote: Exact same errorCode: Select all
__asm__ __volatile__ ("pushfl; \ pushl $0x1b; \ pushl %0; \ iret"::"r"((unsigned int)ring3_code));
For an interrupt, the CPU pops EIP, then CS, then EFLAGS, so for your code what does it pop for EFLAGS?
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.