Long jump in 64-bits: instruction not supported

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.
chris13524
Member
Member
Posts: 45
Joined: Sat Feb 27, 2016 10:52 pm

Re: Long jump in 64-bits: instruction not supported

Post by chris13524 »

I tried your code:

Code: Select all

[GLOBAL gdt_flush]
gdt_flush:
   mov rax, [rsp+4]
   lgdt [rax]

   mov rax, 0x10
   mov ds, rax
   mov es, rax
   mov fs, rax
   mov gs, rax
   mov ss, rax

   lea rax, [rel .flush]
   push 0x08
   push rax
   retf
.flush:
   ret
But it's giving me this exception:

Code: Select all

!!!! X64 Exception Type - 000000000000000D     CPU Apic ID - 00000000 !!!!
RIP  - 000000000673F325, CS  - 0000000000000028, RFLAGS - 0000000000000246
ExceptionData - 0000000000000000
RAX  - 07F94B4000000000, RCX - 00000000000000E9, RDX - 0000000000000068
RBX  - 0000000006744860, RSP - 0000000007F94B18, RBP - 00000000067448C8
RSI  - 0000000000000000, RDI - 00000000067448C8
R8   - 0000000000000000, R9  - 0000000000000674, R10 - 00000000000003F8
R11  - 0000000000000040, R12 - 0000000000000000, R13 - 0000000000000000
R14  - 0000000000000000, R15 - 0000000000000000
DS   - 0000000000000008, ES  - 0000000000000008, FS  - 0000000000000008
GS   - 0000000000000008, SS  - 0000000000000008
CR0  - 0000000080000033, CR2 - 0000000000000000, CR3 - 0000000007F33000
CR4  - 0000000000000668, CR8 - 0000000000000000
DR0  - 0000000000000000, DR1 - 0000000000000000, DR2 - 0000000000000000
DR3  - 0000000000000000, DR6 - 00000000FFFF0FF0, DR7 - 0000000000000400
GDTR - 0000000007F1CE98 000000000000003F, LDTR - 0000000000000000
IDTR - 0000000007C07018 0000000000000FFF,   TR - 0000000000000000
FXSAVE_STATE - 0000000007F94770
!!!! Find PE image (No PDB)  (ImageBase=000000000673A000, EntryPoint=000000000673F34C) !!!!
My operating system:
https://github.com/neonorb/aura
jnc100
Member
Member
Posts: 775
Joined: Mon Apr 09, 2007 12:10 pm
Location: London, UK
Contact:

Re: Long jump in 64-bits: instruction not supported

Post by jnc100 »

UEFI code shouldn't be a shared object. It should be in the PE DLL format so it is potentially relocatable (it usually won't have to be), but shouldn't require runtime linking.

edit: additionally, if this code is called from C then the first argument will not be in [rsp+4] but rather in rcx.

Regards,
John.
User avatar
~
Member
Member
Posts: 1228
Joined: Tue Mar 06, 2007 11:17 am
Libera.chat IRC: ArcheFire

Re: Long jump in 64-bits: instruction not supported

Post by ~ »

Your question could probably be expressed in an index entry that says:
Loading a 64-bit GDT

Looks like it needs a background before and after loading the GDT.

Before, to know which CPU state we are in (do we need to load the GDT outside any function, etc.?).

After, to know which mechanism to use to try to flush the CPU execution state. Among other things, paging must be fully set up before entering 64-bit mode.

I remember having written a test 64-bit kernel with base file name "kernel.asm" or "kernel64.asm" in pure assembly. I'll see if I can find it in my 5TB+ archives.
Last edited by ~ on Thu Aug 25, 2016 10:51 am, edited 1 time in total.
chris13524
Member
Member
Posts: 45
Joined: Sat Feb 27, 2016 10:52 pm

Re: Long jump in 64-bits: instruction not supported

Post by chris13524 »

I'm already running fine in 64-bit mode, UEFI started me off in this. All I was trying to do is to get interrupts working. I can log messages, write to the screen, etc.
My operating system:
https://github.com/neonorb/aura
chris13524
Member
Member
Posts: 45
Joined: Sat Feb 27, 2016 10:52 pm

Re: Long jump in 64-bits: instruction not supported

Post by chris13524 »

edit: additionally, if this code is called from C then the first argument will not be in [rsp+4] but rather in rcx.
It's being called from C++, does this work the same? Use rcx?
My operating system:
https://github.com/neonorb/aura
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Long jump in 64-bits: instruction not supported

Post by iansjack »

In the 64-bit ABI paramaters are passed in rdi, rsi, rdx, rcx, r8, r9 (and then pushed to the stack if there are more parameters). So if your function has only one parameter it will be passed in rdi. You can always look at the generated code if you are unsure.

Edit I should have added - this is the ABI for UNIX-type object files, as would be generated by gcc. The Windows 64-bit ABI is different and uses rcx, rdx, r8, and r9. I was assuming, from the forward slashes in path names, that you are using a UNIX-like system.
chris13524
Member
Member
Posts: 45
Joined: Sat Feb 27, 2016 10:52 pm

Re: Long jump in 64-bits: instruction not supported

Post by chris13524 »

iansjack wrote:In the 64-bit ABI paramaters are passed in rdi, rsi, rdx, rcx, r8, r9 (and then pushed to the stack if there are more parameters). So if your function has only one parameter it will be passed in rdi. You can always look at the generated code if you are unsure.

Edit I should have added - this is the ABI for UNIX-type object files, as would be generated by gcc. The Windows 64-bit ABI is different and uses rcx, rdx, r8, and r9. I was assuming, from the forward slashes in path names, that you are using a UNIX-like system.
Alright, I changed my code to use rdi, however, it's doing that "find PE image error again":

Code: Select all

BITS 64
DEFAULT REL

[GLOBAL gdt_flush]
gdt_flush:
   mov rax, [rdi]
   lgdt [rax]

   mov rax, 0x10
   mov ds, rax
   mov es, rax
   mov fs, rax
   mov gs, rax
   mov ss, rax

   lea rax, [rel .flush]
   push 0x08
   push rax
   retf
.flush:
   ret

[GLOBAL tss_flush]    ; Allows our C code to call tss_flush().
tss_flush:
   mov rax, 0x2B      ; Load the index of our TSS structure - The index is
                     ; 0x28, as it is the 5th selector and each is 8 bytes
                     ; long, but we set the bottom two bits (making 0x2B)
                     ; so that it has an RPL of 3, not zero.
   ltr ax            ; Load 0x2B into the task state register.
   ret
This is happening during the gdt_flush section, figured that out using console output:

Code: Select all

!!!! X64 Exception Type - 000000000000000E     CPU Apic ID - 00000000 !!!!
RIP  - 000000000673E353, CS  - 0000000000000028, RFLAGS - 0000000000000206
ExceptionData - 0000000000000000
RAX  - 000006744940002F, RCX - 0000000007EA9980, RDX - 0000000000000002
RBX  - 00000000067448C0, RSP - 0000000007F94B18, RBP - 0000000006744928
RSI  - 0000000007DD0B10, RDI - 0000000006744928
R8   - 0000000007DC475A, R9  - 0000000007F948EC, R10 - 00000000000003F8
R11  - 0000000000000040, R12 - 0000000000000000, R13 - 0000000000000000
R14  - 0000000000000000, R15 - 0000000000000000
DS   - 0000000000000008, ES  - 0000000000000008, FS  - 0000000000000008
GS   - 0000000000000008, SS  - 0000000000000008
CR0  - 0000000080000033, CR2 - 000006744940002F, CR3 - 0000000007F33000
CR4  - 0000000000000668, CR8 - 0000000000000000
DR0  - 0000000000000000, DR1 - 0000000000000000, DR2 - 0000000000000000
DR3  - 0000000000000000, DR6 - 00000000FFFF0FF0, DR7 - 0000000000000400
GDTR - 0000000007F1CE98 000000000000003F, LDTR - 0000000000000000
IDTR - 0000000007C07018 0000000000000FFF,   TR - 0000000000000000
FXSAVE_STATE - 0000000007F94770
!!!! Find PE image (No PDB)  (ImageBase=0000000006739000, EntryPoint=000000000673E37C) !!!!
My operating system:
https://github.com/neonorb/aura
Octocontrabass
Member
Member
Posts: 5587
Joined: Mon Mar 25, 2013 7:01 pm

Re: Long jump in 64-bits: instruction not supported

Post by Octocontrabass »

chris13524 wrote:

Code: Select all

   mov rax, [rdi]
   lgdt [rax]
Are you sure about that? Without seeing your function prototype, I can't tell exactly what you were going for, but I suspect you really want something like this:

Code: Select all

    lgdt [rdi]
(If you compile with -mabi=ms, use the ms_abi attribute on this function, or use a build of GCC that targets Microsoft's ABI by default, you should use RCX instead of RDI.)
Boris
Member
Member
Posts: 145
Joined: Sat Nov 07, 2015 3:12 pm

Re: Long jump in 64-bits: instruction not supported

Post by Boris »

Always remember that the only 64 bit instruction with 64bit immediate parameter is Mov.
So one should do:

Code: Select all

mov rax, .label
push 8
push rax
retf
Post Reply