summaryrefslogtreecommitdiff
path: root/src/vm/amd64/tizenasanenv.S
blob: ee4728561e0934118dc7031407f2e732aae92649 (plain)
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