lib/stabilizer/src/root.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 //! Randomizes a program's memory layout by choosing heap addresses, stack frame
2 //! padding, and code addresses at random (*layout randomization*), so that a
3 //! benchmark can run over many layouts. A single build fixes the addresses of
4 //! its code, its stack frames, and its heap blocks, and those addresses decide
5 //! which cache lines and branch predictor entries collide. A caller comparing
6 //! two builds of a benchmark wants the difference to come from the code, while
7 //! the addresses the linker and the allocator happened to choose vary from run
8 //! to run.
9 //!
10 //! The heap that keeps a pool of slots per size class and serves each request
11 //! from a slot drawn at random is the *shuffle allocator*. The shuffle
12 //! allocator fills every slot ahead of time and shuffles the pool, then puts a
13 //! fresh block in the drawn slot's place. A request larger than the configured
14 //! maximum bypasses the shuffling and goes to the allocator the caller supplied
15 //! at init, the *backing allocator*.
16 //!
17 //! Each call takes a per-call padding size drawn from a refillable table
18 //! (*stack pad*), so a frame sits at a different offset each time.
19 //!
20 //! The state that relocates registered functions to fresh addresses and
21 //! rewrites their entry traps is the *code randomizer*. Those entry traps catch
22 //! the next call, and the code randomizer moves the layout again every 500
23 //! milliseconds.
24 //!
25 //! One seed drives the heap, the stack pads, and the code layout together, so a
26 //! run repeats when the seed repeats. The defaults follow the published
27 //! Stabilizer runtime: 256 shuffle slots, 32 MiB regions, 32-byte code
28 //! alignment, 16-byte stack alignment, and a 500 millisecond interval.
29
30 const code_mod = @import("code.zig");
31 const config_mod = @import("config.zig");
32 const heap_mod = @import("heap.zig");
33 const intrinsics_mod = @import("intrinsics.zig");
34 const rng_mod = @import("rng.zig");
35 const runtime_mod = @import("runtime.zig");
36 const stack_mod = @import("stack.zig");
37
38 pub const default_seed = config_mod.default_seed;
39 pub const default_shuffle_slots = config_mod.default_shuffle_slots;
40 pub const default_region_size = config_mod.default_region_size;
41 pub const code_alignment = config_mod.code_alignment;
42 pub const stack_alignment = config_mod.stack_alignment;
43 pub const rerandomize_interval_ms = config_mod.rerandomize_interval_ms;
44 pub const max_stack_pad_unit = config_mod.max_stack_pad_unit;
45
46 pub const Config = config_mod.Config;
47 pub const HeapConfig = config_mod.HeapConfig;
48 pub const StackConfig = config_mod.StackConfig;
49 pub const CodeConfig = config_mod.CodeConfig;
50 pub const Reference = config_mod.Reference;
51
52 pub const Marsaglia = rng_mod.Marsaglia;
53 pub const StackPad = stack_mod.StackPad;
54 pub const StackPads = stack_mod.StackPads;
55 pub const ShuffleAllocator = heap_mod.ShuffleAllocator;
56 pub const sizeClass = heap_mod.sizeClass;
57 pub const powif = intrinsics_mod.powif;
58 pub const memset_i8 = intrinsics_mod.memset_i8;
59 pub const memset_i16 = intrinsics_mod.memset_i16;
60 pub const memset_i32 = intrinsics_mod.memset_i32;
61 pub const memset_i64 = intrinsics_mod.memset_i64;
62 pub const FunctionId = code_mod.FunctionId;
63 pub const LocationId = code_mod.LocationId;
64 pub const FunctionOptions = code_mod.FunctionOptions;
65 pub const FunctionImageOptions = code_mod.FunctionImageOptions;
66 pub const FunctionRangeOptions = code_mod.FunctionRangeOptions;
67 pub const FunctionEntryState = code_mod.FunctionEntryState;
68 pub const FunctionStackPad = code_mod.FunctionStackPad;
69 pub const FunctionLocation = code_mod.FunctionLocation;
70 pub const CodeRandomizer = code_mod.CodeRandomizer;
71 pub const ConstructorFn = runtime_mod.ConstructorFn;
72 pub const Runtime = runtime_mod.Runtime;