1#[derive(Debug)]
2pub struct ElfHeader {
3 pub e_ident: [u8; 16], pub e_type: u16, pub e_machine: u16, pub e_version: u32, pub e_entry: u64, pub e_phoff: u64, pub e_shoff: u64, pub e_flags: u32, pub e_ehsize: u16, pub e_phentsize: u16, pub e_phnum: u16, pub e_shentsize: u16, pub e_shnum: u16, pub e_shstrndx: u16, }
18
19#[derive(Debug)]
20pub struct ProgramHeader {
21 pub p_type: u32, pub p_flags: u32, pub p_offset: u64, pub p_vaddr: u64, pub p_paddr: u64, pub p_filesz: u64, pub p_memsz: u64, pub p_align: u64, }
30
31impl ElfHeader {
32 const SOLANA_IDENT: [u8; 16] = [
33 0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ];
41 const SOLANA_TYPE: u16 = 3; const SOLANA_MACHINE: u16 = 247; const SOLANA_VERSION: u32 = 1; const ELF64_HEADER_SIZE: u16 = 64;
45 const PROGRAM_HEADER_SIZE: u16 = 56;
46 const SECTION_HEADER_SIZE: u16 = 64;
47
48 pub fn new() -> Self {
49 Self {
50 e_ident: Self::SOLANA_IDENT,
51 e_type: Self::SOLANA_TYPE,
52 e_machine: Self::SOLANA_MACHINE,
53 e_version: Self::SOLANA_VERSION,
54 e_entry: 0,
55 e_phoff: Self::ELF64_HEADER_SIZE as u64,
56 e_shoff: 0,
57 e_flags: 0,
58 e_ehsize: Self::ELF64_HEADER_SIZE,
59 e_phentsize: Self::PROGRAM_HEADER_SIZE,
60 e_phnum: 0,
61 e_shentsize: Self::SECTION_HEADER_SIZE,
62 e_shnum: 0,
63 e_shstrndx: 0,
64 }
65 }
66
67 pub fn bytecode(&self) -> Vec<u8> {
68 let mut bytecode = Vec::with_capacity(Self::ELF64_HEADER_SIZE as usize);
69
70 bytecode.extend_from_slice(&self.e_ident);
72
73 bytecode.extend_from_slice(&self.e_type.to_le_bytes());
75 bytecode.extend_from_slice(&self.e_machine.to_le_bytes());
76 bytecode.extend_from_slice(&self.e_version.to_le_bytes());
77 bytecode.extend_from_slice(&self.e_entry.to_le_bytes());
78 bytecode.extend_from_slice(&self.e_phoff.to_le_bytes());
79 bytecode.extend_from_slice(&self.e_shoff.to_le_bytes());
80 bytecode.extend_from_slice(&self.e_flags.to_le_bytes());
81 bytecode.extend_from_slice(&self.e_ehsize.to_le_bytes());
82 bytecode.extend_from_slice(&self.e_phentsize.to_le_bytes());
83 bytecode.extend_from_slice(&self.e_phnum.to_le_bytes());
84 bytecode.extend_from_slice(&self.e_shentsize.to_le_bytes());
85 bytecode.extend_from_slice(&self.e_shnum.to_le_bytes());
86 bytecode.extend_from_slice(&self.e_shstrndx.to_le_bytes());
87
88 bytecode
89 }
90}
91
92impl ProgramHeader {
93
94 const PT_LOAD: u32 = 1; const PT_DYNAMIC: u32 = 2; const PF_X: u32 = 1; const PF_W: u32 = 2; const PF_R: u32 = 4; const PAGE_SIZE: u64 = 4096; pub fn new_load(offset: u64, size: u64, executable: bool) -> Self {
104 let flags = if executable {
105 Self::PF_R | Self::PF_X } else {
107 Self::PF_R };
109
110 ProgramHeader {
111 p_type: Self::PT_LOAD,
112 p_flags: flags,
113 p_offset: offset,
114 p_vaddr: offset,
115 p_paddr: offset,
116 p_filesz: size,
117 p_memsz: size,
118 p_align: Self::PAGE_SIZE
119 }
120 }
121
122 pub fn new_dynamic(offset: u64, size: u64) -> Self {
123 ProgramHeader {
124 p_type: Self::PT_DYNAMIC,
125 p_flags: Self::PF_R | Self::PF_W,
126 p_offset: offset,
127 p_vaddr: offset,
128 p_paddr: offset,
129 p_filesz: size,
130 p_memsz: size,
131 p_align: 8
132 }
133 }
134
135 pub fn bytecode(&self) -> Vec<u8> {
136 let mut bytecode = Vec::with_capacity(56); bytecode.extend_from_slice(&self.p_type.to_le_bytes());
139 bytecode.extend_from_slice(&self.p_flags.to_le_bytes());
140 bytecode.extend_from_slice(&self.p_offset.to_le_bytes());
141 bytecode.extend_from_slice(&self.p_vaddr.to_le_bytes());
142 bytecode.extend_from_slice(&self.p_paddr.to_le_bytes());
143 bytecode.extend_from_slice(&self.p_filesz.to_le_bytes());
144 bytecode.extend_from_slice(&self.p_memsz.to_le_bytes());
145 bytecode.extend_from_slice(&self.p_align.to_le_bytes());
146
147 bytecode
148 }
149}
150#[derive(Debug)]
151pub struct SectionHeader {
152 sh_name: u32, sh_type: u32, sh_flags: u64, sh_addr: u64, sh_offset: u64, sh_size: u64, sh_link: u32, sh_info: u32, sh_addralign: u64, sh_entsize: u64, }
163
164impl SectionHeader {
165 pub const SHT_NULL: u32 = 0; pub const SHT_PROGBITS: u32 = 1; pub const SHT_STRTAB: u32 = 3; pub const SHT_NOBITS: u32 = 8; pub const SHT_DYNAMIC: u32 = 6; pub const SHT_DYNSYM: u32 = 11; pub const SHT_REL: u32 = 9; pub const SHF_WRITE: u64 = 0x1; pub const SHF_ALLOC: u64 = 0x2; pub const SHF_EXECINSTR: u64 = 0x4; pub fn new(name_offset: u32, sh_type: u32, flags: u64, addr: u64, offset: u64, size: u64, link: u32, info: u32, addralign: u64, entsize: u64) -> Self {
180 Self {
181 sh_name: name_offset,
182 sh_type,
183 sh_flags: flags,
184 sh_addr: addr,
185 sh_offset: offset,
186 sh_size: size,
187 sh_link: link,
188 sh_info: info,
189 sh_addralign: addralign,
190 sh_entsize: entsize,
191 }
192 }
193
194 pub fn bytecode(&self) -> Vec<u8> {
195 let mut bytecode = Vec::with_capacity(64); bytecode.extend_from_slice(&self.sh_name.to_le_bytes());
198 bytecode.extend_from_slice(&self.sh_type.to_le_bytes());
199 bytecode.extend_from_slice(&self.sh_flags.to_le_bytes());
200 bytecode.extend_from_slice(&self.sh_addr.to_le_bytes());
201 bytecode.extend_from_slice(&self.sh_offset.to_le_bytes());
202 bytecode.extend_from_slice(&self.sh_size.to_le_bytes());
203 bytecode.extend_from_slice(&self.sh_link.to_le_bytes());
204 bytecode.extend_from_slice(&self.sh_info.to_le_bytes());
205 bytecode.extend_from_slice(&self.sh_addralign.to_le_bytes());
206 bytecode.extend_from_slice(&self.sh_entsize.to_le_bytes());
207
208 bytecode
209 }
210}