Skip to main content

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}