6
6
;
7
7
; requirements:
8
8
; g_sysinf SYSTEM_INFO ; populated global structure
9
- ;
10
- ; TODO: reuse handler code for initialization
11
9
12
10
virtual DATA. 64
13
11
FreeList__block_bytes dq 64 ; 64, freelist item size
@@ -25,7 +23,7 @@ namespace FreeList
25
23
26
24
REGISTER equ r15 ; default global get/set register (or state explicitly)
27
25
28
- ; these two function are why freelist
26
+ ; this is why freelists are used - these two macros
29
27
macro get reg0 *, reg1:FreeList.REGISTER
30
28
mov reg0 , reg1
31
29
mov reg1 , [ reg1 ]
@@ -35,6 +33,40 @@ macro put reg0*, reg1:FreeList.REGISTER
35
33
mov reg1 , reg0
36
34
end macro
37
35
36
+ ; The default is to configure through global variables, and let the OS
37
+ ; select a base address.
38
+ macro initialize total_bytes: [ FreeList__total_bytes ], \
39
+ start_address: 0
40
+ local fail
41
+ ; setup exception handler as first in hierarchy
42
+ AddVectoredExceptionHandler 1 , & FreeList.Handler
43
+ mov [ FreeList__hVector ], rax
44
+ xchg rcx , rax
45
+ jrcxz fail
46
+
47
+ ; set region start/size here
48
+ mov rdx , total_bytes
49
+ mov [ FreeList__end_address ], rdx
50
+ VirtualAlloc start_address , rdx , MEM_RESERVE , PAGE_NOACCESS
51
+ xchg rcx , rax
52
+ jrcxz fail
53
+ mov [ FreeList__base_address ], rcx
54
+ add [ FreeList__end_address ], rcx
55
+ call FreeList.Handler.extend
56
+ mov FreeList.REGISTER , [ FreeList__base_address ]
57
+ xchg ecx , eax
58
+ fail:
59
+ purge FreeList.initialize
60
+ end macro ; RCX zero on error
61
+
62
+ macro destroy
63
+ RemoveVectoredExceptionHandler [ FreeList__hVector ]
64
+ VirtualFree [ FreeList__base_address ], 0 , MEM_RELEASE
65
+ purge FreeList.destroy
66
+ end macro
67
+
68
+
69
+ ; Chaining is only used by the Handler.
38
70
; NOTE: `base` is advanced to address after `bytes`
39
71
macro chain base *, reg0 *, reg1 *, bytes: [ g_sysinf.dwAllocationGranularity ]
40
72
local more
@@ -47,7 +79,6 @@ more: mov reg0, base
47
79
jnz more
48
80
end macro
49
81
50
-
51
82
; TODO: test if just handling EXCEPTION_ACCESS_VIOLATION is the same?
52
83
; NOTE: Cannot be used during a system service.
53
84
;
@@ -78,7 +109,7 @@ Handler:
78
109
; system removes the `PAGE_GUARD` status, commit next granule, set next guard page
79
110
; invalidate guard address, no guard page set
80
111
and [ FreeList__guard_address ], 0
81
-
112
+ .extend:
82
113
virtual at rbp - .frame
83
114
rq 4
84
115
.frame := $ - $$
@@ -92,7 +123,7 @@ Handler:
92
123
; create free blocks
93
124
chain rcx , rdx , rax , [ g_sysinf.dwAllocationGranularity ]
94
125
95
- ; no guard page possible for large allocation unit
126
+ ; no guard page possible for last allocation unit
96
127
cmp rcx , [ FreeList__end_address ]
97
128
jz .execute
98
129
VirtualAlloc rcx , dword [ g_sysinf.dwPageSize ], \
@@ -101,7 +132,6 @@ Handler:
101
132
jrcxz .commit_fail
102
133
mov [ FreeList__guard_address ], rcx
103
134
.execute:
104
- ; moved guard page, okay to continue
105
135
assert (EXCEPTION_CONTINUE_EXECUTION and 0xFFFF_FFFF) = 0xFFFF_FFFF
106
136
or eax , EXCEPTION_CONTINUE_EXECUTION
107
137
leave
@@ -111,42 +141,4 @@ Handler:
111
141
leave
112
142
jmp .search
113
143
114
-
115
- ; The default is to configure through global variables, and let the OS
116
- ; select a base address.
117
- macro initialize total_bytes: [ FreeList__total_bytes ], \
118
- start_bytes:dword [ g_sysinf.dwAllocationGranularity ], \
119
- start_address: 0
120
- local fail0 , fail
121
- ; setup exception handler as first in hierarchy
122
- AddVectoredExceptionHandler 1 , & FreeList.Handler
123
- mov [ FreeList__hVector ], rax
124
- xchg rcx , rax
125
- jrcxz fail0
126
-
127
- ; set region start/size here
128
- mov rdx , total_bytes
129
- mov [ FreeList__end_address ], rdx
130
- VirtualAlloc start_address , rdx , MEM_RESERVE , PAGE_NOACCESS
131
- xchg rcx , rax
132
- fail0:
133
- jrcxz fail
134
- VirtualAlloc rcx , start_bytes , MEM_COMMIT , PAGE_READWRITE
135
- xchg rcx , rax
136
- jrcxz fail
137
- ; update start/end addresses
138
- mov [ FreeList__base_address ], rcx
139
- add [ FreeList__end_address ], rcx
140
-
141
- ; create free blocks
142
- FreeList.chain rcx , rdx , rax , [ g_sysinf.dwAllocationGranularity ]
143
-
144
- VirtualAlloc rcx , dword [ g_sysinf.dwPageSize ], \
145
- MEM_COMMIT , PAGE_READWRITE or PAGE_GUARD
146
- xchg rcx , rax
147
- mov [ FreeList__guard_address ], rcx
148
- mov FreeList.REGISTER , [ FreeList__base_address ]
149
- fail:
150
- end macro ; RCX zero on error
151
-
152
144
end namespace ; FreeList
0 commit comments