, QEMU , , "" , , , "" - , , , .
, call, ret , , . , thunk-, .
QEMU
OP () , call ret, . ( QEMU) , call ret , , , .
, OP , , . , QEMU : Tiny Code Generator (TCG), , ( , ). , TCG, .

3 . , . , -, ret call call ret .
: -, C return_address(), , main(), :
#include <stdlib.h>
#include <stdio.h>
__attribute__ ((noinline)) void* return_address() {
return __builtin_return_address(0);
}
int main(int argc, char **argv) {
void *a = return_address();
printf("%p\n", a);
}
noinline , gcc , call !
gcc -g -O1 -march=native :
0000000000400546 <return_address>:
400546: 48 8b 04 24 mov rax,QWORD PTR [rsp]
40054a: c3 ret
000000000040054b <main>:
40054b: 48 83 ec 08 sub rsp,0x8
40054f: b8 00 00 00 00 mov eax,0x0
400554: e8 ed ff ff ff call 400546 <return_address>
400559: 48 89 c2 mov rdx,rax
40055c: be 04 06 40 00 mov esi,0x400604
400561: bf 01 00 00 00 mov edi,0x1
400566: b8 00 00 00 00 mov eax,0x0
40056b: e8 c0 fe ff ff call 400430 <__printf_chk@plt>
400570: b8 00 00 00 00 mov eax,0x0
400575: 48 83 c4 08 add rsp,0x8
400579: c3 ret
, return_address() [rsp] , OP. main() rdx, printf .
, return_address , , 0x400559:
400554: e8 ed ff ff ff call 400546 <return_address>
400559: 48 89 c2 mov rdx,rax
... , , :
person@host:~/dev/test-c$ ./qemu-test
0x400559
QEMU:
person@host:~/dev/test-c$ qemu-x86_64 ./qemu-test
0x400559
! , QEMU ( ), - .
? -d in_asm,out_asm QEMU, , .
-, , ( IN - , OUT - , QEMU , AT & T, , QEMU):
IN: main
0x000000000040054b: sub $0x8,%rsp
0x000000000040054f: mov $0x0,%eax
0x0000000000400554: callq 0x400546
OUT: [size=123]
0x557c9cf33a40: mov -0x8(%r14),%ebp
0x557c9cf33a44: test %ebp,%ebp
0x557c9cf33a46: jne 0x557c9cf33aac
0x557c9cf33a4c: mov 0x20(%r14),%rbp
0x557c9cf33a50: sub $0x8,%rbp
0x557c9cf33a54: mov %rbp,0x20(%r14)
0x557c9cf33a58: mov $0x8,%ebx
0x557c9cf33a5d: mov %rbx,0x98(%r14)
0x557c9cf33a64: mov %rbp,0x90(%r14)
0x557c9cf33a6b: xor %ebx,%ebx
0x557c9cf33a6d: mov %rbx,(%r14)
0x557c9cf33a70: sub $0x8,%rbp
0x557c9cf33a74: mov $0x400559,%ebx
0x557c9cf33a79: mov %rbx,0x0(%rbp)
0x557c9cf33a7d: mov %rbp,0x20(%r14)
0x557c9cf33a81: mov $0x11,%ebp
0x557c9cf33a86: mov %ebp,0xa8(%r14)
0x557c9cf33a8d: jmpq 0x557c9cf33a92
0x557c9cf33a92: movq $0x400546,0x80(%r14)
0x557c9cf33a9d: mov $0x7f177ad8a690,%rax
0x557c9cf33aa7: jmpq 0x557c9cef8196
0x557c9cf33aac: mov $0x7f177ad8a693,%rax
0x557c9cf33ab6: jmpq 0x557c9cef8196
:
0x557c9cf33a74: mov $0x400559,%ebx
0x557c9cf33a79: mov %rbx,0x0(%rbp)
, "" ( , , rbp). , return_address call. , :
0x557c9cf33a92: movq $0x400546,0x80(%r14)
0x557c9cf33a9d: mov $0x7f177ad8a690,%rax
0x557c9cf33aa7: jmpq 0x557c9cef8196
r14 QEMU (.. ). 0x400546 ( return_address ) , r14, 0x7f177ad8a690 rax 0x557c9cef8196. ( ) , -, thunk. , , , , , rax, return_address, :
----------------
IN: return_address
0x0000000000400546: mov (%rsp),%rax
0x000000000040054a: retq
OUT: [size=64]
0x55c131ef9ad0: mov -0x8(%r14),%ebp
0x55c131ef9ad4: test %ebp,%ebp
0x55c131ef9ad6: jne 0x55c131ef9b01
0x55c131ef9adc: mov 0x20(%r14),%rbp
0x55c131ef9ae0: mov 0x0(%rbp),%rbx
0x55c131ef9ae4: mov %rbx,(%r14)
0x55c131ef9ae7: mov 0x0(%rbp),%rbx
0x55c131ef9aeb: add $0x8,%rbp
0x55c131ef9aef: mov %rbp,0x20(%r14)
0x55c131ef9af3: mov %rbx,0x80(%r14)
0x55c131ef9afa: xor %eax,%eax
0x55c131ef9afc: jmpq 0x55c131ebe196
0x55c131ef9b01: mov $0x7f9ba51f7713,%rax
0x55c131ef9b0b: jmpq 0x55c131ebe196
, -, "" ebp ( r14 + 0x20, , , ) "" ( mov 0x0(%rbp),%rbx) , r14 (mov %rbx,0x80(%r14)).
, jmpq 0x55c131ebe196, epilogue QEMU:
0x55c131ebe196: add $0x488,%rsp
0x55c131ebe19d: pop %r15
0x55c131ebe19f: pop %r14
0x55c131ebe1a1: pop %r13
0x55c131ebe1a3: pop %r12
0x55c131ebe1a5: pop %rbx
0x55c131ebe1a6: pop %rbp
0x55c131ebe1a7: retq
, "" . , "" , , , rsp. , rsp, QEMU , .
, "", , QEMU, . , - , (.. rsp, , [rsp]).
:
__attribute__ ((noinline)) void* return_address() {
return __builtin_frame_address(0);
}
, 0x7fffad33c100, , 0x40007ffd00 QEMU. , . , , , - ASLR (Linux Windows ). , ( QEMU).
, , . -, QEMU " ". , , - , ( , argc). , , ââ : .
- - - , QEMU . , , , R + X. , GP, QEMU , , , .. .
, , - .
, " " : SMC, , , .