elf_header.rs 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. use {
  2. crate::errors::DisassemblerError,
  3. object::{Endianness, read::elf::ElfFile64},
  4. serde::{Deserialize, Serialize, Serializer},
  5. std::str,
  6. };
  7. pub const EI_MAGIC: [u8; 4] = *b"\x7fELF"; // ELF magic
  8. pub const EI_CLASS: u8 = 0x02; // 64-bit
  9. pub const EI_DATA: u8 = 0x01; // Little endian
  10. pub const EI_VERSION: u8 = 0x01; // Version 1
  11. pub const EI_OSABI: u8 = 0x00; // System V
  12. pub const EI_ABIVERSION: u8 = 0x00; // No ABI version
  13. pub const EI_PAD: [u8; 7] = [0u8; 7]; // Padding
  14. pub const E_TYPE: u16 = 0x03; // ET_DYN - shared object
  15. pub const E_MACHINE: u16 = 0xf7; // Berkeley Packet Filter
  16. pub const E_MACHINE_SBPF: u16 = 0x0107; // Solana Berkeley Packet Filter
  17. pub const E_VERSION: u32 = 0x01; // Original version of BPF
  18. fn elf_magic<S>(magic: &[u8; 4], serializer: S) -> Result<S::Ok, S::Error>
  19. where
  20. S: Serializer,
  21. {
  22. let s = String::from_utf8_lossy(magic);
  23. serializer.serialize_str(&s)
  24. }
  25. #[derive(Debug, Clone, Serialize, Deserialize)]
  26. pub struct ELFHeader {
  27. #[serde(serialize_with = "elf_magic")]
  28. pub ei_magic: [u8; 4],
  29. pub ei_class: u8,
  30. pub ei_data: u8,
  31. pub ei_version: u8,
  32. pub ei_osabi: u8,
  33. pub ei_abiversion: u8,
  34. pub ei_pad: [u8; 7],
  35. pub e_type: u16,
  36. pub e_machine: u16,
  37. pub e_version: u32,
  38. pub e_entry: u64,
  39. pub e_phoff: u64,
  40. pub e_shoff: u64,
  41. pub e_flags: u32,
  42. pub e_ehsize: u16,
  43. pub e_phentsize: u16,
  44. pub e_phnum: u16,
  45. pub e_shentsize: u16,
  46. pub e_shnum: u16,
  47. pub e_shstrndx: u16,
  48. }
  49. impl ELFHeader {
  50. pub fn from_elf_file(elf_file: &ElfFile64<Endianness>) -> Result<Self, DisassemblerError> {
  51. let endian = elf_file.endian();
  52. let elf_header = elf_file.elf_header();
  53. // Extract ELF header fields.
  54. let e_ident = elf_header.e_ident;
  55. let e_type = elf_header.e_type.get(endian);
  56. let e_machine = elf_header.e_machine.get(endian);
  57. let e_version = elf_header.e_version.get(endian);
  58. let e_entry = elf_header.e_entry.get(endian);
  59. let e_phoff = elf_header.e_phoff.get(endian);
  60. let e_shoff = elf_header.e_shoff.get(endian);
  61. let e_flags = elf_header.e_flags.get(endian);
  62. let e_ehsize = elf_header.e_ehsize.get(endian);
  63. let e_phentsize = elf_header.e_phentsize.get(endian);
  64. let e_phnum = elf_header.e_phnum.get(endian);
  65. let e_shentsize = elf_header.e_shentsize.get(endian);
  66. let e_shnum = elf_header.e_shnum.get(endian);
  67. let e_shstrndx = elf_header.e_shstrndx.get(endian);
  68. // Validate ELF header fields.
  69. if e_ident.magic.ne(&EI_MAGIC)
  70. || e_ident.class.ne(&EI_CLASS)
  71. || e_ident.data.ne(&EI_DATA)
  72. || e_ident.version.ne(&EI_VERSION)
  73. || e_ident.os_abi.ne(&EI_OSABI)
  74. || e_ident.abi_version.ne(&EI_ABIVERSION)
  75. || e_ident.padding.ne(&EI_PAD)
  76. || (e_machine.ne(&E_MACHINE) && e_machine.ne(&E_MACHINE_SBPF))
  77. || e_version.ne(&E_VERSION)
  78. {
  79. return Err(DisassemblerError::NonStandardElfHeader);
  80. }
  81. Ok(ELFHeader {
  82. ei_magic: e_ident.magic,
  83. ei_class: e_ident.class,
  84. ei_data: e_ident.data,
  85. ei_version: e_ident.version,
  86. ei_osabi: e_ident.os_abi,
  87. ei_abiversion: e_ident.abi_version,
  88. ei_pad: e_ident.padding,
  89. e_type,
  90. e_machine,
  91. e_version,
  92. e_entry,
  93. e_phoff,
  94. e_shoff,
  95. e_flags,
  96. e_ehsize,
  97. e_phentsize,
  98. e_phnum,
  99. e_shentsize,
  100. e_shnum,
  101. e_shstrndx,
  102. })
  103. }
  104. pub fn to_bytes(&self) -> Vec<u8> {
  105. let mut b = self.ei_magic.to_vec();
  106. b.extend_from_slice(&[
  107. self.ei_class,
  108. self.ei_data,
  109. self.ei_version,
  110. self.ei_osabi,
  111. self.ei_abiversion,
  112. ]);
  113. b.extend_from_slice(&self.ei_pad);
  114. b.extend_from_slice(&self.e_type.to_le_bytes());
  115. b.extend_from_slice(&self.e_machine.to_le_bytes());
  116. b.extend_from_slice(&self.e_version.to_le_bytes());
  117. b.extend_from_slice(&self.e_entry.to_le_bytes());
  118. b.extend_from_slice(&self.e_phoff.to_le_bytes());
  119. b.extend_from_slice(&self.e_shoff.to_le_bytes());
  120. b.extend_from_slice(&self.e_flags.to_le_bytes());
  121. b.extend_from_slice(&self.e_ehsize.to_le_bytes());
  122. b.extend_from_slice(&self.e_phentsize.to_le_bytes());
  123. b.extend_from_slice(&self.e_phnum.to_le_bytes());
  124. b.extend_from_slice(&self.e_shentsize.to_le_bytes());
  125. b.extend_from_slice(&self.e_shnum.to_le_bytes());
  126. b.extend_from_slice(&self.e_shstrndx.to_le_bytes());
  127. b
  128. }
  129. }
  130. #[cfg(test)]
  131. mod tests {
  132. use {
  133. crate::{
  134. elf_header::{
  135. E_MACHINE, E_MACHINE_SBPF, E_TYPE, E_VERSION, EI_ABIVERSION, EI_CLASS, EI_DATA,
  136. EI_MAGIC, EI_OSABI, EI_PAD, EI_VERSION,
  137. },
  138. program::Program,
  139. },
  140. hex_literal::hex,
  141. };
  142. #[test]
  143. fn test_elf_header() {
  144. let program = Program::from_bytes(&hex!("7F454C460201010000000000000000000300F700010000002001000000000000400000000000000028020000000000000000000040003800030040000600050001000000050000002001000000000000200100000000000020010000000000003000000000000000300000000000000000100000000000000100000004000000C001000000000000C001000000000000C0010000000000003C000000000000003C000000000000000010000000000000020000000600000050010000000000005001000000000000500100000000000070000000000000007000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007912A000000000007911182900000000B7000000010000002D21010000000000B70000000000000095000000000000001E0000000000000004000000000000000600000000000000C0010000000000000B0000000000000018000000000000000500000000000000F0010000000000000A000000000000000C00000000000000160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000120001002001000000000000300000000000000000656E747279706F696E7400002E74657874002E64796E737472002E64796E73796D002E64796E616D6963002E73687374727461620000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000010000000600000000000000200100000000000020010000000000003000000000000000000000000000000008000000000000000000000000000000170000000600000003000000000000005001000000000000500100000000000070000000000000000400000000000000080000000000000010000000000000000F0000000B0000000200000000000000C001000000000000C001000000000000300000000000000004000000010000000800000000000000180000000000000007000000030000000200000000000000F001000000000000F0010000000000000C00000000000000000000000000000001000000000000000000000000000000200000000300000000000000000000000000000000000000FC010000000000002A00000000000000000000000000000001000000000000000000000000000000")).unwrap();
  145. // Verify ELF header fields match expected constants.
  146. assert_eq!(program.elf_header.ei_magic, EI_MAGIC);
  147. assert_eq!(program.elf_header.ei_class, EI_CLASS);
  148. assert_eq!(program.elf_header.ei_data, EI_DATA);
  149. assert_eq!(program.elf_header.ei_version, EI_VERSION);
  150. assert_eq!(program.elf_header.ei_osabi, EI_OSABI);
  151. assert_eq!(program.elf_header.ei_abiversion, EI_ABIVERSION);
  152. assert_eq!(program.elf_header.ei_pad, EI_PAD);
  153. assert_eq!(program.elf_header.e_type, E_TYPE);
  154. assert!(
  155. program.elf_header.e_machine == E_MACHINE
  156. || program.elf_header.e_machine == E_MACHINE_SBPF
  157. );
  158. assert_eq!(program.elf_header.e_version, E_VERSION);
  159. }
  160. }