surfpool_core/surfnet/noop_program.rs
1/// Minimal valid SBF ELF (352 bytes) — just returns SUCCESS (r0=0).
2///
3/// Used as a placeholder in `init_programdata_account` to satisfy LiteSVM's
4/// ELF validation when bootstrapping program accounts. This gets stripped
5/// by `write_program_data_account_with_offset` before actual program data
6/// is written.
7///
8/// Layout (352 bytes):
9/// 0x000..0x040 ELF64 header (ET_DYN, EM_SBPF=0x107, SBPFv0, entry=0x78)
10/// 0x040..0x078 1× PT_LOAD program header (text at 0x78, 16 bytes, RX)
11/// 0x078..0x088 .text section: mov64 r0,0 ; exit
12/// 0x088..0x099 .shstrtab contents: "\0.text\0.shstrtab\0"
13/// 0x099..0x0A0 padding (7 bytes, align section headers to 8)
14/// 0x0A0..0x0E0 Section header [0]: SHT_NULL
15/// 0x0E0..0x120 Section header [1]: .text
16/// 0x120..0x160 Section header [2]: .shstrtab
17pub const NOOP_PROGRAM_ELF: &[u8] = &[
18 // ===== ELF64 Header (64 bytes) =====
19 // e_ident: EI_MAG0..3, EI_CLASS=2(64-bit), EI_DATA=1(LE), EI_VERSION=1,
20 // EI_OSABI=0, padding
21 0x7F, b'E', b'L', b'F', 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
22 // e_type=ET_DYN(3), e_machine=EM_SBPF(0x107)
23 0x03, 0x00, 0x07, 0x01, // e_version=1
24 0x01, 0x00, 0x00, 0x00, // e_entry=0x78 (start of .text)
25 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
26 // e_phoff=0x40 (program headers right after ELF header)
27 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
28 // e_shoff=0xA0 (section headers at offset 160)
29 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // e_flags=0 (SBPFv0)
30 0x00, 0x00, 0x00, 0x00, // e_ehsize=64
31 0x40, 0x00, // e_phentsize=56
32 0x38, 0x00, // e_phnum=1
33 0x01, 0x00, // e_shentsize=64
34 0x40, 0x00, // e_shnum=3
35 0x03, 0x00, // e_shstrndx=2
36 0x02, 0x00, // ===== Program Header (56 bytes) =====
37 // p_type=PT_LOAD(1)
38 0x01, 0x00, 0x00, 0x00, // p_flags=PF_R|PF_X(5)
39 0x05, 0x00, 0x00, 0x00, // p_offset=0x78
40 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // p_vaddr=0x78
41 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // p_paddr=0x78
42 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // p_filesz=16
43 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // p_memsz=16
44 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // p_align=8
45 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46 // ===== .text section (16 bytes at 0x78) =====
47 // mov64 r0, 0 (opcode=0xb7, dst=r0, src=0, off=0, imm=0)
48 0xB7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49 // exit (opcode=0x95, dst=0, src=0, off=0, imm=0)
50 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51 // ===== .shstrtab contents (17 bytes at 0x88) =====
52 // "\0.text\0.shstrtab\0"
53 0x00, b'.', b't', b'e', b'x', b't', 0x00, b'.', b's', b'h', b's', b't', b'r', b't', b'a', b'b',
54 0x00, // ===== Padding to align section headers to 8 bytes (7 bytes) =====
55 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
56 // ===== Section Header [0]: SHT_NULL (64 bytes at 0xA0) =====
57 0x00, 0x00, 0x00, 0x00, // sh_name=0
58 0x00, 0x00, 0x00, 0x00, // sh_type=SHT_NULL(0)
59 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sh_flags=0
60 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sh_addr=0
61 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sh_offset=0
62 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sh_size=0
63 0x00, 0x00, 0x00, 0x00, // sh_link=0
64 0x00, 0x00, 0x00, 0x00, // sh_info=0
65 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sh_addralign=0
66 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sh_entsize=0
67 // ===== Section Header [1]: .text (64 bytes at 0xE0) =====
68 0x01, 0x00, 0x00, 0x00, // sh_name=1 (index into .shstrtab: ".text")
69 0x01, 0x00, 0x00, 0x00, // sh_type=SHT_PROGBITS(1)
70 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sh_flags=SHF_ALLOC|SHF_EXECINSTR(6)
71 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sh_addr=0x78
72 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sh_offset=0x78
73 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sh_size=16
74 0x00, 0x00, 0x00, 0x00, // sh_link=0
75 0x00, 0x00, 0x00, 0x00, // sh_info=0
76 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sh_addralign=8
77 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sh_entsize=0
78 // ===== Section Header [2]: .shstrtab (64 bytes at 0x120) =====
79 0x07, 0x00, 0x00, 0x00, // sh_name=7 (index into .shstrtab: ".shstrtab")
80 0x03, 0x00, 0x00, 0x00, // sh_type=SHT_STRTAB(3)
81 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sh_flags=0
82 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sh_addr=0
83 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sh_offset=0x88
84 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sh_size=17
85 0x00, 0x00, 0x00, 0x00, // sh_link=0
86 0x00, 0x00, 0x00, 0x00, // sh_info=0
87 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sh_addralign=1
88 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sh_entsize=0
89];
90
91#[cfg(test)]
92mod tests {
93 use super::*;
94
95 #[test]
96 fn test_noop_program_elf_size() {
97 assert_eq!(NOOP_PROGRAM_ELF.len(), 352);
98 }
99}