-
Notifications
You must be signed in to change notification settings - Fork 0
/
fill.pwn
135 lines (114 loc) · 2.91 KB
/
fill.pwn
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
/*
Replaces FillMemory calls with inline "fill" instructions.
- heix
*/
#if defined _CGEN_fill_
#endinput
#endif
#define _CGEN_fill_
static stock ReplaceFillInstr(const match[CodeScanner])
{
new
cip = CodeScanGetMatchAddressData(match);
#pragma warning push
#pragma warning disable 213
/* parameters */
new
size = CodeScanGetMatchHole(match, 0),
value = CodeScanGetMatchHole(match, 1),
destination = CodeScanGetMatchHole(match, 2),
bool:is_global = (ReadAmxMemory(cip + 24) == _:RelocateOpcode(OP_CONST_PRI)) || (ReadAmxMemory(cip + 16) == _:RelocateOpcode(OP_PUSH_C));
#pragma warning pop
// nop current opcodes so we can generate our own
CodeScanNOPMatch(match);
new ctx[AsmContext];
AsmInitPtr(ctx, cip, 24);
@emit const.pri value
if(is_global)
{
@emit const.alt destination
}
else
{
@emit addr.alt destination
}
@emit fill (size * cellbytes)
return 1;
}
FillMemory(arr[], val = 0, size = sizeof(arr))
{
#pragma unused arr, val, size
return 0;
}
public OnJITCompile()
{
new scanner[CodeScanner];
CodeScanInit(scanner);
/*
The compiler has diferents ways of generating code, so we want to match all off them:
the "_fast" suffix indicates the compiler generates single "push.c"/"push.adr" opcodes for parameter pushing
the "_cpri" suffix indicates the compiler generates two (three, actually) opcodes:
"const.pri"/"addr.pri" and "push.pri"
*/
new local_fast[CodeScanMatcher];
CodeScanMatcherInit(local_fast, &ReplaceFillInstr);
CodeScanMatcherPattern(local_fast,
OP(PUSH_C, ???)
OP(PUSH_C, ???)
OP(PUSH_ADR, ???)
OP(PUSH_C, 0xc)
OP(CALL, __addressof(FillMemory))
);
CodeScanAddMatcher(scanner, local_fast);
new local_cpri[CodeScanMatcher];
CodeScanMatcherInit(local_cpri, &ReplaceFillInstr);
CodeScanMatcherPattern(local_cpri,
OP(CONST_PRI, ???)
OP(PUSH_PRI)
OP(CONST_PRI, ???)
OP(PUSH_PRI)
OP(ADDR_PRI, ???)
OP(PUSH_PRI)
OP(PUSH_C, 0xc)
OP(CALL, __addressof(FillMemory))
);
CodeScanAddMatcher(scanner, local_cpri);
new global_cpri[CodeScanMatcher];
CodeScanMatcherInit(global_cpri, &ReplaceFillInstr);
CodeScanMatcherPattern(global_cpri,
OP(CONST_PRI, ???)
OP(PUSH_PRI)
OP(CONST_PRI, ???)
OP(PUSH_PRI)
OP(CONST_PRI, ???)
OP(PUSH_PRI)
OP(PUSH_C, 0xc)
OP(CALL, __addressof(FillMemory))
);
CodeScanAddMatcher(scanner, global_cpri);
new global_fast[CodeScanMatcher];
CodeScanMatcherInit(global_fast, &ReplaceFillInstr);
CodeScanMatcherPattern(global_fast,
OP(PUSH_C, ???)
OP(PUSH_C, ???)
OP(PUSH_C, ???)
OP(PUSH_C, 0xc)
OP(CALL, __addressof(FillMemory))
);
CodeScanAddMatcher(scanner, global_fast);
CodeScanRun(scanner);
#if defined CGEN_FILL_OnJITCompile
return CGEN_FILL_OnJITCompile();
#else
return 1;
#endif
}
#if defined _ALS_OnJITCompile
#undef OnJITCompile
#else
#define _ALS_OnJITCompile
#endif
#define OnJITCompile CGEN_FILL_OnJITCompile
#if defined CGEN_FILL_OnJITCompile
forward CGEN_FILL_OnJITCompile();
#endif