OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 04, 2021 11:06 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: GP Excpetion when doing retf in Long Mode
PostPosted: Tue May 28, 2019 5:02 am 
Offline

Joined: Tue Jun 12, 2018 11:10 am
Posts: 4
Emulator: QEMU
Compiler: x86_64-w64-mingw32-gcc (and as)

I'm trying to simulate a far jump via retf. For testing purposes I try to jump to the same segment I'm already in. The following code is executed after ExitBootServices():

Code:
.intel_syntax noprefix
.global test_retf

test_retf:
   push rbp
   mov rbp, rsp

   mov ax, cs
   push ax # push cs
   push jump_target # push target
   retf

jump_target:
   nop # do something after far jump
   pop rbp # Return
   ret

.att_syntax noprefix


Executing this code produces a GP Exception:

Code:
!!!! X64 Exception Type - 0D(#GP - General Protection)  CPU Apic ID - 00000000 !!!!
ExceptionData - 0000000000009090
RIP  - 00000000066FB010, CS  - 0000000000000038, RFLAGS - 0000000000000046
RAX  - 0000000000000038, RCX - 0000000000000000, RDX - 0000000000000000
RBX  - 0000000000000000, RSP - 0000000007F1F986, RBP - 0000000007F1F990
RSI  - 0000000000000009, RDI - 0000000006E92118
R8   - 0000000007F1F93C, R9  - 0000000000000078, R10 - 0000000007BC4840
R11  - 0000000036E11C9A, R12 - 0000000000000000, R13 - 0000000006BDA018
R14  - 0000000000000000, R15 - 0000000007650000
DS   - 0000000000000030, ES  - 0000000000000030, FS  - 0000000000000030
GS   - 0000000000000030, SS  - 0000000000000030
CR0  - 0000000080010033, CR2 - 0000000000000000, CR3 - 0000000007C01000
CR4  - 0000000000000668, CR8 - 0000000000000000
DR0  - 0000000000000000, DR1 - 0000000000000000, DR2 - 0000000000000000
DR3  - 0000000000000000, DR6 - 00000000FFFF0FF0, DR7 - 0000000000000400
GDTR - 0000000007BEEA98 0000000000000047, LDTR - 0000000000000000
IDTR - 000000000765A018 0000000000000FFF,   TR - 0000000000000000
FXSAVE_STATE - 0000000007F1F5E0
!!!! Find image based on IP(0x66FB010) (No PDB)  (ImageBase=00000000066FA000, EntryPoint=00000000066FB020) !!!!

Can someone point me to what I'm doing wrong? I've read the RETF section from the AMD Programmer’s Manual Volume 3 and cannot find out what I'm doing wrong.


Last edited by Freggar on Tue May 28, 2019 6:40 am, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: GP Excpetion when doing retf in Long Mode
PostPosted: Tue May 28, 2019 5:52 am 
Online
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 2817
In long mode, "push ax" still only pushes two bytes onto the stack. You need an instruction that will push eight bytes, such as "push rax".

(This might not be the only problem, but it's the only one I can spot right now.)


Top
 Profile  
 
 Post subject: Re: GP Excpetion when doing retf in Long Mode
PostPosted: Tue May 28, 2019 7:03 am 
Offline

Joined: Tue Jun 12, 2018 11:10 am
Posts: 4
Thanks for the pointer, doing
Code:
mov rax, cs
push rax

instead, will yield the same error. Are you sure that I need to push 8 bytes?
Quote:
All stack pops are determined by the operand size. If necessary, the target rIP is zero-extended to 64
bits before assuming program control.

AMD Programmer’s Manual Volume 3 -- RET (far)

This leads me to believe that I need to push 2 bytes since the CS register is 2 bytes.


Top
 Profile  
 
 Post subject: Re: GP Excpetion when doing retf in Long Mode
PostPosted: Tue May 28, 2019 7:44 am 
Online
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 2817
Freggar wrote:
Are you sure that I need to push 8 bytes?

Yes, assuming you're using a far return with a 64-bit operand size. I'm not familiar with GAS for x86 assembly, but I know NASM and YASM disagree on whether "retf" should be encoded with a 32-bit operand size or a 64-bit operand size. You might need to write something else to get the right operand size.

It's not made clear in the section of the manual you quote, but CS is popped using the operand size, discarding the unused high-order bits if the operand size is 32-bit or 64-bit.


Top
 Profile  
 
 Post subject: Re: GP Excpetion when doing retf in Long Mode
PostPosted: Wed May 29, 2019 3:10 am 
Offline

Joined: Tue Jun 12, 2018 11:10 am
Posts: 4
Yes, seems like it was an issue with operand size. I got it working by using the code from this stackoverflow post
Code:
sub $16, %rsp
movq $8, 8(%rsp)
movabsq $fun, %rax
mov %rax, (%rsp)
lretq

The "lretq" translates to "rex.W retf" in objdump, so you probably need to specify 64-bit operand size.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group