1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
// Scheme of saving registers to the stack
// +--------+----------------------+
// | | value |
// | offset | size | register name |
// +--------+------+---------------+
// | 0x00 | 8 | --- | (returnt addr)
// | -0x08 | 8 | rax |
// | -0x10 | 8 | r11 |
// | -0x18 | 8 | r10 |
// | -0x20 | 8 | r9 |
// | -0x28 | 8 | r8 |
// | -0x30 | 8 | rcx |
// | -0x38 | 8 | rdx |
// | -0x40 | 8 | rsi |
// | -0x48 | 8 | rdi |
// | -0x50 | 16 | xmm7 |
// | -0x60 | 16 | xmm6 |
// | -0x70 | 16 | xmm5 |
// | -0x80 | 16 | xmm4 |
// | -0x90 | 16 | xmm3 |
// | -0xa0 | 16 | xmm2 |
// | -0xb0 | 16 | xmm1 |
// | -0xc0 | 16 | xmm0 |
#define GENERAL_SAVED_REGS_COUNT 9
#define GENERAL_SAVED_REGS_SIZE (8 * GENERAL_SAVED_REGS_COUNT)
.macro PUSH_GENERAL_REGS
push %rdi // 1st argument
push %rsi // 2nd argument
push %rdx // 3rd argument, 2nd return register
push %rcx // 4th argument
push %r8 // 5th argument
push %r9 // 6th argument
push %r10 // 1st return register
push %r11 // temporary register
push %rax // temporary register
.endm
.macro POP_GENERAL_REGS
pop %rax
pop %r11
pop %r10
pop %r9
pop %r8
pop %rcx
pop %rdx
pop %rsi
pop %rdi
.endm
#define XMM_SAVED_REGS_COUNT 8
#define XMM_SAVED_REGS_SIZE (16 * XMM_SAVED_REGS_COUNT)
.macro PUSH_XMM_REGS
sub $XMM_SAVED_REGS_SIZE, %rsp
movaps %xmm0, 0x00(%rsp)
movaps %xmm1, 0x10(%rsp)
movaps %xmm2, 0x20(%rsp)
movaps %xmm3, 0x30(%rsp)
movaps %xmm4, 0x40(%rsp)
movaps %xmm5, 0x50(%rsp)
movaps %xmm6, 0x60(%rsp)
movaps %xmm7, 0x70(%rsp)
.endm
.macro POP_XMM_REGS
movaps 0x70(%rsp), %xmm7
movaps 0x60(%rsp), %xmm6
movaps 0x50(%rsp), %xmm5
movaps 0x40(%rsp), %xmm4
movaps 0x30(%rsp), %xmm3
movaps 0x20(%rsp), %xmm2
movaps 0x10(%rsp), %xmm1
movaps 0x00(%rsp), %xmm0
add $XMM_SAVED_REGS_SIZE, %rsp
.endm
#define RETADDR_OFFSET (GENERAL_SAVED_REGS_SIZE + XMM_SAVED_REGS_SIZE)
.macro PUSH_REGS
PUSH_GENERAL_REGS
PUSH_XMM_REGS
.endm
.macro POP_REGS
POP_XMM_REGS
POP_GENERAL_REGS
.endm
// Export symbols
.global tizenASanWrapper
.global tizenASanWrapperSize
.global tizenASanWrapperEntryOffset
.text
.code64
tizenASanWrapper:
// !!! ATTENTION !!!
// Don't move this labels (target, pushAddr, popAddr)
// because they mapped to AuxiliaryCalls struct from src/vm/tizenasanenv.cpp
target: .quad 0xdeadbeef0badc0de
pushAddr: .quad 0xdeadbeef0badc0de // void pushAddr(LPVOID addr)
popAddr: .quad 0xdeadbeef0badc0de // LPVOID popAddr()
entryPointer:
// Save context
PUSH_REGS
// Save the return address and call 'pre handler'
mov RETADDR_OFFSET(%rsp), %rdi // rdi: get return address
call *pushAddr(%rip) // save the return address
// Change the return address
call next
next:
pop %rax // rax: get current rip
add $(postLabel - next), %rax // rax: add offset to 'postLabel'
mov %rax, RETADDR_OFFSET(%rsp) // change the return address
// Restore context
POP_REGS
// Call original function
jmp *target(%rip)
postLabel:
sub $8, %rsp // add space for the return addr
// Save context
PUSH_REGS
// Get the return address and call 'post handler'
call *popAddr(%rip) // rax: get the return address
mov %rax, (RETADDR_OFFSET)(%rsp) // restore the return address
// Restore context
POP_REGS
// Return
ret
tizenASanWrapperSize: .long . - tizenASanWrapper
tizenASanWrapperEntryOffset: .long entryPointer - tizenASanWrapper
|