elf_utilities/section/
base.rs

1use super::{Contents32, Contents64, Section32, Section64, Shdr32, Shdr64, Type};
2
3#[derive(Debug, Clone)]
4pub(crate) struct Section {
5    pub name: String,
6    pub header: Shdr,
7
8    pub contents: Contents,
9}
10
11#[derive(Debug, Clone)]
12pub(crate) enum Shdr {
13    Shdr64(Shdr64),
14    Shdr32(Shdr32),
15}
16
17#[derive(Debug, Clone)]
18pub(crate) enum Contents {
19    Contents64(Contents64),
20    Contents32(Contents32),
21}
22
23#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
24pub struct StrTabEntry {
25    pub v: String,
26    pub idx: usize,
27}
28
29impl Section {
30    pub fn new(hdr: Shdr) -> Self {
31        let is_64bit = matches!(hdr, Shdr::Shdr64(_));
32        Self {
33            name: Default::default(),
34            contents: if is_64bit {
35                Contents::Contents64(Contents64::Raw(Default::default()))
36            } else {
37                Contents::Contents32(Contents32::Raw(Default::default()))
38            },
39            header: hdr,
40        }
41    }
42
43    pub fn as_64bit(&self) -> Section64 {
44        Section64 {
45            name: self.name.clone(),
46            contents: self.contents.as_64bit(),
47            header: self.header.as_64bit(),
48        }
49    }
50    pub fn as_32bit(&self) -> Section32 {
51        Section32 {
52            name: self.name.clone(),
53            contents: self.contents.as_32bit(),
54            header: self.header.as_32bit(),
55        }
56    }
57
58    pub fn ty(&self) -> Type {
59        match self.header {
60            Shdr::Shdr32(shdr) => shdr.get_type(),
61            Shdr::Shdr64(shdr) => shdr.get_type(),
62        }
63    }
64    pub fn name_idx(&self) -> usize {
65        match self.header {
66            Shdr::Shdr32(shdr) => shdr.sh_name as usize,
67            Shdr::Shdr64(shdr) => shdr.sh_name as usize,
68        }
69    }
70    pub fn offset(&self) -> usize {
71        match self.header {
72            Shdr::Shdr32(shdr) => shdr.sh_offset as usize,
73            Shdr::Shdr64(shdr) => shdr.sh_offset as usize,
74        }
75    }
76    pub fn size(&self) -> usize {
77        match self.header {
78            Shdr::Shdr32(shdr) => shdr.sh_size as usize,
79            Shdr::Shdr64(shdr) => shdr.sh_size as usize,
80        }
81    }
82    pub fn entry_size(&self) -> usize {
83        match self.header {
84            Shdr::Shdr32(shdr) => shdr.sh_entsize as usize,
85            Shdr::Shdr64(shdr) => shdr.sh_entsize as usize,
86        }
87    }
88    pub fn link(&self) -> usize {
89        match self.header {
90            Shdr::Shdr32(shdr) => shdr.sh_link as usize,
91            Shdr::Shdr64(shdr) => shdr.sh_link as usize,
92        }
93    }
94}
95
96impl Contents {
97    pub fn as_64bit(&self) -> Contents64 {
98        match self {
99            Contents::Contents64(contents) => contents.clone(),
100            _ => unreachable!(),
101        }
102    }
103    pub fn as_32bit(&self) -> Contents32 {
104        match self {
105            Contents::Contents32(contents) => contents.clone(),
106            _ => unreachable!(),
107        }
108    }
109    pub fn as_strtab(&self) -> Vec<StrTabEntry> {
110        match self {
111            Contents::Contents32(contents) => match contents {
112                Contents32::StrTab(v) => v.clone(),
113                _ => unreachable!(),
114            },
115            Contents::Contents64(contents) => match contents {
116                Contents64::StrTab(v) => v.clone(),
117                _ => unreachable!(),
118            },
119        }
120    }
121}
122
123impl Shdr {
124    pub fn as_64bit(&self) -> Shdr64 {
125        match self {
126            Self::Shdr64(shdr) => *shdr,
127            _ => unreachable!(),
128        }
129    }
130    pub fn as_32bit(&self) -> Shdr32 {
131        match self {
132            Self::Shdr32(shdr) => *shdr,
133            _ => unreachable!(),
134        }
135    }
136}