sol_alloc_free_ is how the first Solana programs got heap memory: they asked the runtime for it. New deployments that use it have been rejected on mainnet since August 2023, yet it still runs every day, mostly inside one program, Memo v1. And a newer program format can deploy it again.
SIMD-0706, proposed on 26 October, closes that gap and puts a price on every remaining call; Agave #16661 implements it. Both were open on 4 November. We scanned program binaries for the syscall, counted its calls by running Memo v1’s mainnet binary, and checked the deployment rule before and after.
How a banned syscall became deployable again
The ban was written in May 2022 and its feature, disable_deploy_of_alloc_free_syscall, activated on mainnet on 2 August 2023. Agave builds the deployment environment without the syscall, while the execution environment keeps it, so programs deployed earlier keep running.
That check works by name. Programs built for SBPFv0 to v2 link each syscall by name, and deployment rejects a name the environment lacks. SBPFv3, through static syscalls, calls syscalls by number, and Agave’s on-chain verifier does not look the numbers up. We built one small program that calls sol_alloc_free_ for both versions and ran Agave’s deployment check on it with solana-sbpf 0.27.0:
deploy today deploy with SIMD-0706 loads to run
SBPFv0 rejected: UnresolvedSymbol rejected yes
SBPFv3 accepted rejected: InvalidSyscall yesThe fix needed the VM first. solana-sbpf 0.27.0, released on 3 November, adds an option that makes the verifier reject static calls to unregistered syscalls (#292). Agave #16661 turns it on for deployments and upgrades behind a feature that still has a placeholder key. It leaves it off for ExtendProgram and core-program migrations, so nothing already deployed is newly rejected. The SIMD’s title covers the wider effect: any SBPFv3 call to a syscall the environment does not register is rejected, not only this one.
Finding the syscall in a binary
The two formats hide syscalls in different places, so the scan has two halves. We wrote it with nothing but Python’s standard library:
1. solana program dump <PROGRAM_ID> program.so
2. read e_flags in the ELF header: 0-2 is SBPFv0-v2, 3 is SBPFv3
3. SBPFv0-v2: in every SHT_REL section, take relocations of type 10
(R_SBF_64_32) whose dynamic symbol has value 0; the symbol
name is the syscall
4. SBPFv3: in .text, take call instructions (opcode 0x85) with
source register 0; the immediate is murmur3_32(name)
5. sol_alloc_free_ is 0x83F00E8FA relocation against a defined symbol is a call between the program’s own functions, not a syscall, which is why the value check matters. We checked the scanner against our own builds before pointing it at mainnet.
Who still depends on it
The SIMD counts 209 older programs that may call the syscall, names Memo v1 as the only heavy user, and lists three more with any use in the past month. We fetched those four binaries from mainnet, plus fourteen of the most-used programs:
program loader deployed call sites
Memo v1 BPF loader v1 - 4
95o7H8q... upgradeable Jan 2023 11
B1hM7ws... upgradeable Jun 2022 9
CpbvNz3... upgradeable May 2022 32
Memo v2, SPL Token, Token-2022, Associated Token,
Token Metadata, Jupiter v6, Raydium AMM v4 and CLMM,
Orca Whirlpools, Meteora DLMM, Pump.fun, Squads v4,
Stake, Address Lookup Table noneAll four callers reference it; none of the fourteen do. Every binary in the sample is SBPFv0, the busiest programs included, so the SBPFv3 gap is about programs that do not exist yet. The three upgradeable callers can still be upgraded, but only with a build that drops the syscall.
The SIMD dates the ban to 2022, when it was written. On mainnet it took effect in August 2023, and 95o7H8q… was deployed with the syscall in January 2023, more than six months before that.
What Memo v1 will pay
SIMD-0706 charges each call the syscall base cost, 100 compute units. We ran Memo v1’s mainnet binary in solana-sbpf with its input laid out the way Agave’s deprecated loader lays it out, and Agave’s allocator for that loader: a bump allocator over a 32 KiB heap whose frees do nothing. Memo v1 never touches its accounts, but the SDK entrypoint it was built with allocates while unpacking them.
accounts allocs frees calls CU today CU with SIMD-0706
0 0 0 0 259 259
1 3 3 6 661 1,261
2 5 5 10 724 1,724
3 7 7 14 1,097 2,497
4 9 9 18 1,160 2,960That is 4n + 2 calls for n accounts, the SIMD’s figure, half of them frees that cost nothing today and would cost 100 each. Today’s compute units are the harness’s instruction counts, which matched mainnet simulations for zero, one and two accounts exactly. With one account a memo nearly doubles in cost; without accounts, which the SIMD finds in 75% of Memo v1 instructions, nothing changes.
Memo v1 cannot be upgraded, so its callers can only move to a different program. Memo v2 does not use the syscall, but it is not a drop-in replacement: it requires every account passed to it to have signed, which Memo v1 never checked.
Across runtime versions
Only the last three rows depend on the new verifier option, and they apply only once the feature activates. A deployment tool that already checks SBPFv3 binaries locally, as the Solana CLI does against the cluster’s current features, catches both cases today.
What this does not show
We scanned 18 programs, not the corpus; the count of 209 and the usage figures are the SIMD’s. The call counts come from solana-sbpf 0.26.0 with Agave’s serialization and allocator rebuilt in our harness, checked against mainnet simulation; the deployment results from solana-sbpf 0.27.0 with Agave’s deployment environment rebuilt the same way, not from a validator. Our local Agave 4.2.1 test validator, which activates every feature, could not run Memo v1 with accounts at all: it failed with an access violation in its input region. Its bundled Memo v1 is also a different build from mainnet’s, with the same syscalls.
sol_alloc_free_: Questions People Actually Ask
What is sol_alloc_free_ on Solana?
The original heap syscall: a program asked the runtime to allocate memory from its 32 KiB heap instead of running its own allocator. Frees are accepted but do nothing. Modern programs bring their own bump allocator; what still calls it is old SDK entrypoints, on every allocation and free while unpacking the accounts they are given.
Can you still deploy a Solana program that uses sol_alloc_free_?
Not an SBPFv0, v1 or v2 program: since 2 August 2023 mainnet’s deployment check has rejected the name. An SBPFv3 program, which calls syscalls by number, still deploys today, because the on-chain verifier does not look the number up. SIMD-0706, with Agave #16661, would reject it.
How do I check whether my Solana program calls sol_alloc_free_?
Dump the program with solana program dump and look at its syscalls. For SBPFv0 to v2, list the R_SBF_64_32 relocations against undefined dynamic symbols; the syscall names appear as symbol names. For SBPFv3, look for call instructions with source register 0 and the immediate 0x83F00E8F, the murmur3 hash of the name.
How much more will Memo v1 cost under SIMD-0706?
Memo v1 calls the syscall 4n + 2 times for n accounts and not at all with none. At 100 compute units per call, an instruction with one account goes from 661 to 1,261 units and one with two accounts from 724 to 1,724. Instructions without accounts stay at 259.
What does SIMD-0706 change for SBPFv3 programs?
Deployment and upgrades would reject any SBPFv3 program that calls sol_alloc_free_ or any syscall the deployment environment does not register. Today such programs deploy and fail only when they reach the call. Programs already deployed are not re-checked.
The one-line version
sol_alloc_free_ survives in old SBPFv0 binaries led by Memo v1, which SIMD-0706 would charge 100 compute units per call, while SBPFv3 can still deploy it today because the on-chain verifier does not check syscall numbers, a gap solana-sbpf 0.27.0 and Agave #16661 close.
Sources: SIMD-0706 and Agave #16661 as of 4 November; solana-sbpf 0.27.0 and #292; Agave master at 4fd1753c; the 2022 ban and its mainnet feature account. Binaries are mainnet’s; the scanner and harnesses are our own.