Skip to content

Commit 30ede72

Browse files
committed
Add asan support for various allocators
1 parent 8032db3 commit 30ede72

17 files changed

+289
-89
lines changed

base/runtime/default_temp_allocator_arena.odin

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package runtime
22

33
import "base:intrinsics"
4+
import "base:sanitizer"
45

56
DEFAULT_ARENA_GROWING_MINIMUM_BLOCK_SIZE :: uint(DEFAULT_TEMP_ALLOCATOR_BACKING_SIZE)
67

@@ -43,6 +44,8 @@ memory_block_alloc :: proc(allocator: Allocator, capacity: uint, alignment: uint
4344
block.base = ([^]byte)(uintptr(block) + base_offset)
4445
block.capacity = uint(end - uintptr(block.base))
4546

47+
sanitizer.address_poison(block.base, block.capacity)
48+
4649
// Should be zeroed
4750
assert(block.used == 0)
4851
assert(block.prev == nil)
@@ -52,6 +55,7 @@ memory_block_alloc :: proc(allocator: Allocator, capacity: uint, alignment: uint
5255
memory_block_dealloc :: proc(block_to_free: ^Memory_Block, loc := #caller_location) {
5356
if block_to_free != nil {
5457
allocator := block_to_free.allocator
58+
sanitizer.address_unpoison(block_to_free.base, block_to_free.capacity)
5559
mem_free(block_to_free, allocator, loc)
5660
}
5761
}
@@ -83,6 +87,7 @@ alloc_from_memory_block :: proc(block: ^Memory_Block, min_size, alignment: uint)
8387
return
8488
}
8589
data = block.base[block.used+alignment_offset:][:min_size]
90+
sanitizer.address_unpoison(block.base[block.used:block.used+size])
8691
block.used += size
8792
return
8893
}
@@ -162,6 +167,7 @@ arena_free_all :: proc(arena: ^Arena, loc := #caller_location) {
162167
if arena.curr_block != nil {
163168
intrinsics.mem_zero(arena.curr_block.base, arena.curr_block.used)
164169
arena.curr_block.used = 0
170+
sanitizer.address_poison(arena.curr_block.base, arena.curr_block.capacity)
165171
}
166172
arena.total_used = 0
167173
}
@@ -226,6 +232,7 @@ arena_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
226232
// grow data in-place, adjusting next allocation
227233
block.used = uint(new_end)
228234
data = block.base[start:new_end]
235+
sanitizer.address_unpoison(data)
229236
return
230237
}
231238
}
@@ -299,6 +306,7 @@ arena_temp_end :: proc(temp: Arena_Temp, loc := #caller_location) {
299306
assert(block.used >= temp.used, "out of order use of arena_temp_end", loc)
300307
amount_to_zero := block.used-temp.used
301308
intrinsics.mem_zero(block.base[temp.used:], amount_to_zero)
309+
sanitizer.address_poison(block.base[temp.used:block.capacity])
302310
block.used = temp.used
303311
arena.total_used -= amount_to_zero
304312
}

base/runtime/heap_allocator_windows.odin

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package runtime
22

3+
import "../sanitizer"
4+
35
foreign import kernel32 "system:Kernel32.lib"
46

57
@(private="file")
@@ -16,7 +18,10 @@ foreign kernel32 {
1618

1719
_heap_alloc :: proc "contextless" (size: int, zero_memory := true) -> rawptr {
1820
HEAP_ZERO_MEMORY :: 0x00000008
19-
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY if zero_memory else 0, uint(size))
21+
ptr := HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY if zero_memory else 0, uint(size))
22+
// NOTE(lucas): asan not guarunteed to unpoison win32 heap out of the box, do it ourselves
23+
sanitizer.address_unpoison(ptr, size)
24+
return ptr
2025
}
2126
_heap_resize :: proc "contextless" (ptr: rawptr, new_size: int) -> rawptr {
2227
if new_size == 0 {
@@ -28,7 +33,10 @@ _heap_resize :: proc "contextless" (ptr: rawptr, new_size: int) -> rawptr {
2833
}
2934

3035
HEAP_ZERO_MEMORY :: 0x00000008
31-
return HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ptr, uint(new_size))
36+
new_ptr := HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ptr, uint(new_size))
37+
// NOTE(lucas): asan not guarunteed to unpoison win32 heap out of the box, do it ourselves
38+
sanitizer.address_unpoison(new_ptr, new_size)
39+
return new_ptr
3240
}
3341
_heap_free :: proc "contextless" (ptr: rawptr) {
3442
if ptr == nil {

base/runtime/internal.odin

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,3 +1106,12 @@ __read_bits :: proc "contextless" (dst, src: [^]byte, offset: uintptr, size: uin
11061106
dst[j>>3] |= the_bit<<(j&7)
11071107
}
11081108
}
1109+
1110+
@(no_sanitize_address)
1111+
__asan_unpoison_memory_region :: #force_inline proc "contextless" (address: rawptr, size: uint) {
1112+
foreign {
1113+
__asan_unpoison_memory_region :: proc(address: rawptr, size: uint) ---
1114+
}
1115+
__asan_unpoison_memory_region(address, size)
1116+
}
1117+

0 commit comments

Comments
 (0)