elf_sections.rs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. use header::Tag;
  2. #[derive(Debug)]
  3. pub struct ElfSectionsTag {
  4. inner: *const ElfSectionsTagInner,
  5. offset: usize,
  6. }
  7. pub unsafe fn elf_sections_tag(tag: &Tag, offset: usize) -> ElfSectionsTag {
  8. assert_eq!(9, tag.typ);
  9. let es = ElfSectionsTag {
  10. inner: (tag as *const Tag).offset(1) as *const ElfSectionsTagInner,
  11. offset: offset,
  12. };
  13. assert!((es.get().entry_size * es.get().shndx) <= tag.size);
  14. es
  15. }
  16. #[derive(Clone, Copy, Debug)]
  17. #[repr(C, packed)] // only repr(C) would add unwanted padding at the end
  18. struct ElfSectionsTagInner {
  19. number_of_sections: u32,
  20. entry_size: u32,
  21. shndx: u32, // string table
  22. }
  23. impl ElfSectionsTag {
  24. pub fn sections(&self) -> ElfSectionIter {
  25. let string_section_offset = (self.get().shndx * self.get().entry_size) as isize;
  26. let string_section_ptr = unsafe {
  27. self.first_section().offset(string_section_offset) as *const _
  28. };
  29. ElfSectionIter {
  30. current_section: self.first_section(),
  31. remaining_sections: self.get().number_of_sections,
  32. entry_size: self.get().entry_size,
  33. string_section: string_section_ptr,
  34. offset: self.offset,
  35. }
  36. }
  37. fn first_section(&self) -> *const u8 {
  38. (unsafe { self.inner.offset(1) }) as *const _
  39. }
  40. fn get(&self) -> &ElfSectionsTagInner {
  41. unsafe { &*self.inner }
  42. }
  43. }
  44. #[derive(Clone, Debug)]
  45. pub struct ElfSectionIter {
  46. current_section: *const u8,
  47. remaining_sections: u32,
  48. entry_size: u32,
  49. string_section: *const u8,
  50. offset: usize,
  51. }
  52. impl Iterator for ElfSectionIter {
  53. type Item = ElfSection;
  54. fn next(&mut self) -> Option<ElfSection> {
  55. while self.remaining_sections != 0 {
  56. let section = ElfSection {
  57. inner: self.current_section,
  58. string_section: self.string_section,
  59. entry_size: self.entry_size,
  60. offset: self.offset,
  61. };
  62. self.current_section = unsafe { self.current_section.offset(self.entry_size as isize) };
  63. self.remaining_sections -= 1;
  64. if section.section_type() != ElfSectionType::Unused {
  65. return Some(section);
  66. }
  67. }
  68. None
  69. }
  70. }
  71. #[derive(Debug)]
  72. pub struct ElfSection {
  73. inner: *const u8,
  74. string_section: *const u8,
  75. entry_size: u32,
  76. offset: usize,
  77. }
  78. #[derive(Clone, Copy, Debug)]
  79. #[repr(C, packed)]
  80. struct ElfSectionInner32 {
  81. name_index: u32,
  82. typ: u32,
  83. flags: u32,
  84. addr: u32,
  85. offset: u32,
  86. size: u32,
  87. link: u32,
  88. info: u32,
  89. addralign: u32,
  90. entry_size: u32,
  91. }
  92. #[derive(Clone, Copy, Debug)]
  93. #[repr(C, packed)]
  94. struct ElfSectionInner64 {
  95. name_index: u32,
  96. typ: u32,
  97. flags: u64,
  98. addr: u64,
  99. offset: u64,
  100. size: u64,
  101. link: u32,
  102. info: u32,
  103. addralign: u64,
  104. entry_size: u64,
  105. }
  106. impl ElfSection {
  107. pub fn section_type(&self) -> ElfSectionType {
  108. match self.get().typ() {
  109. 0 => ElfSectionType::Unused,
  110. 1 => ElfSectionType::ProgramSection,
  111. 2 => ElfSectionType::LinkerSymbolTable,
  112. 3 => ElfSectionType::StringTable,
  113. 4 => ElfSectionType::RelaRelocation,
  114. 5 => ElfSectionType::SymbolHashTable,
  115. 6 => ElfSectionType::DynamicLinkingTable,
  116. 7 => ElfSectionType::Note,
  117. 8 => ElfSectionType::Uninitialized,
  118. 9 => ElfSectionType::RelRelocation,
  119. 10 => ElfSectionType::Reserved,
  120. 11 => ElfSectionType::DynamicLoaderSymbolTable,
  121. 0x6000_0000...0x6FFF_FFFF => ElfSectionType::EnvironmentSpecific,
  122. 0x7000_0000...0x7FFF_FFFF => ElfSectionType::ProcessorSpecific,
  123. _ => panic!(),
  124. }
  125. }
  126. pub fn section_type_raw(&self) -> u32 {
  127. self.get().typ()
  128. }
  129. pub fn name(&self) -> &str {
  130. use core::{str, slice};
  131. let name_ptr = unsafe {
  132. self.string_table().offset(self.get().name_index() as isize)
  133. };
  134. let strlen = {
  135. let mut len = 0;
  136. while unsafe { *name_ptr.offset(len) } != 0 {
  137. len += 1;
  138. }
  139. len as usize
  140. };
  141. str::from_utf8(unsafe { slice::from_raw_parts(name_ptr, strlen) }).unwrap()
  142. }
  143. pub fn start_address(&self) -> u64 {
  144. self.get().addr()
  145. }
  146. pub fn end_address(&self) -> u64 {
  147. self.get().addr() + self.get().size()
  148. }
  149. pub fn size(&self) -> u64 {
  150. self.get().size()
  151. }
  152. pub fn addralign(&self) -> u64 {
  153. self.get().addralign()
  154. }
  155. pub fn flags(&self) -> ElfSectionFlags {
  156. ElfSectionFlags::from_bits_truncate(self.get().flags())
  157. }
  158. pub fn is_allocated(&self) -> bool {
  159. self.flags().contains(ElfSectionFlags::ALLOCATED)
  160. }
  161. fn get(&self) -> &ElfSectionInner {
  162. match self.entry_size {
  163. 40 => unsafe { &*(self.inner as *const ElfSectionInner32) },
  164. 64 => unsafe { &*(self.inner as *const ElfSectionInner64) },
  165. _ => panic!(),
  166. }
  167. }
  168. unsafe fn string_table(&self) -> *const u8 {
  169. let addr = match self.entry_size {
  170. 40 => (*(self.string_section as *const ElfSectionInner32)).addr as usize,
  171. 64 => (*(self.string_section as *const ElfSectionInner64)).addr as usize,
  172. _ => panic!(),
  173. };
  174. (addr + self.offset) as *const _
  175. }
  176. }
  177. trait ElfSectionInner {
  178. fn name_index(&self) -> u32;
  179. fn typ(&self) -> u32;
  180. fn flags(&self) -> u64;
  181. fn addr(&self) -> u64;
  182. fn size(&self) -> u64;
  183. fn addralign(&self) -> u64;
  184. }
  185. impl ElfSectionInner for ElfSectionInner32 {
  186. fn name_index(&self) -> u32 {
  187. self.name_index
  188. }
  189. fn typ(&self) -> u32 {
  190. self.typ
  191. }
  192. fn flags(&self) -> u64 {
  193. self.flags.into()
  194. }
  195. fn addr(&self) -> u64 {
  196. self.addr.into()
  197. }
  198. fn size(&self) -> u64 {
  199. self.size.into()
  200. }
  201. fn addralign(&self) -> u64 {
  202. self.addralign.into()
  203. }
  204. }
  205. impl ElfSectionInner for ElfSectionInner64 {
  206. fn name_index(&self) -> u32 {
  207. self.name_index
  208. }
  209. fn typ(&self) -> u32 {
  210. self.typ
  211. }
  212. fn flags(&self) -> u64 {
  213. self.flags
  214. }
  215. fn addr(&self) -> u64 {
  216. self.addr
  217. }
  218. fn size(&self) -> u64 {
  219. self.size
  220. }
  221. fn addralign(&self) -> u64 {
  222. self.addralign.into()
  223. }
  224. }
  225. #[derive(PartialEq, Eq, Debug, Copy, Clone)]
  226. #[repr(u32)]
  227. pub enum ElfSectionType {
  228. Unused = 0,
  229. ProgramSection = 1,
  230. LinkerSymbolTable = 2,
  231. StringTable = 3,
  232. RelaRelocation = 4,
  233. SymbolHashTable = 5,
  234. DynamicLinkingTable = 6,
  235. Note = 7,
  236. Uninitialized = 8,
  237. RelRelocation = 9,
  238. Reserved = 10,
  239. DynamicLoaderSymbolTable = 11,
  240. EnvironmentSpecific = 0x6000_0000,
  241. ProcessorSpecific = 0x7000_0000,
  242. }
  243. bitflags! {
  244. pub struct ElfSectionFlags: u64 {
  245. const WRITABLE = 0x1;
  246. const ALLOCATED = 0x2;
  247. const EXECUTABLE = 0x4;
  248. // plus environment-specific use at 0x0F000000
  249. // plus processor-specific use at 0xF0000000
  250. }
  251. }