1#[derive(Clone, Copy, Debug, PartialEq)]
3pub enum SymbolType {
4 Func,
6 Object,
8 Tls,
10}
11
12#[derive(Clone, Copy, Debug, PartialEq)]
14pub enum SymbolScope {
15 Global,
17 Local,
19 Weak,
21}
22
23#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)]
25pub enum SectionKind {
26 Null,
27 DynStr,
28 DynSym,
29 RelaDyn,
30 RelaPlt,
31 RelDyn,
32 RelPlt,
33 Dynamic,
34 Hash,
35 ShStrTab,
36 Plt,
37 Text,
38 Data,
39 Got,
40 GotPlt,
41 Tls,
42}
43
44#[derive(Debug, Clone)]
46pub struct Content {
47 pub data: Vec<u8>,
49 pub kind: SectionKind,
51}
52
53#[derive(Clone, Debug)]
55pub struct SymbolDesc {
56 pub name: String,
58 pub sym_type: SymbolType,
60 pub scope: SymbolScope,
62 pub content: Option<Content>,
64 pub size: Option<u64>,
66}
67
68impl SymbolDesc {
69 pub fn global_func(name: impl Into<String>, code: &[u8]) -> Self {
71 Self {
72 name: name.into(),
73 sym_type: SymbolType::Func,
74 scope: SymbolScope::Global,
75 content: Some(Content {
76 data: code.to_vec(),
77 kind: SectionKind::Text,
78 }),
79 size: Some(code.len() as u64),
80 }
81 }
82
83 pub fn global_object(name: impl Into<String>, data: &[u8]) -> Self {
85 Self {
86 name: name.into(),
87 sym_type: SymbolType::Object,
88 scope: SymbolScope::Global,
89 content: Some(Content {
90 data: data.to_vec(),
91 kind: SectionKind::Data,
92 }),
93 size: Some(data.len() as u64),
94 }
95 }
96
97 pub fn undefined_func(name: impl Into<String>) -> Self {
99 Self {
100 name: name.into(),
101 sym_type: SymbolType::Func,
102 scope: SymbolScope::Global,
103 content: None,
104 size: None,
105 }
106 }
107
108 pub fn undefined_object(name: impl Into<String>) -> Self {
110 Self {
111 name: name.into(),
112 sym_type: SymbolType::Object,
113 scope: SymbolScope::Global,
114 content: None,
115 size: None,
116 }
117 }
118
119 pub fn global_tls(name: impl Into<String>, data: &[u8]) -> Self {
121 Self {
122 name: name.into(),
123 sym_type: SymbolType::Tls,
124 scope: SymbolScope::Global,
125 content: Some(Content {
126 data: data.to_vec(),
127 kind: SectionKind::Tls,
128 }),
129 size: Some(data.len() as u64),
130 }
131 }
132
133 pub fn undefined_tls(name: impl Into<String>) -> Self {
135 Self {
136 name: name.into(),
137 sym_type: SymbolType::Tls,
138 scope: SymbolScope::Global,
139 content: None,
140 size: None,
141 }
142 }
143
144 pub fn plt_func(name: impl Into<String>, code: Vec<u8>) -> Self {
146 let size = code.len() as u64;
147 Self {
148 name: name.into(),
149 sym_type: SymbolType::Func,
150 scope: SymbolScope::Global,
151 content: Some(Content {
152 data: code,
153 kind: SectionKind::Plt,
154 }),
155 size: Some(size),
156 }
157 }
158
159 pub fn with_size(mut self, size: u64) -> Self {
161 self.size = Some(size);
162 self
163 }
164
165 pub fn with_scope(mut self, scope: SymbolScope) -> Self {
167 self.scope = scope;
168 self
169 }
170}
171
172#[derive(Clone, Copy, PartialEq, Eq, Debug)]
174pub struct RelocType(pub u32);
175
176impl RelocType {
177 pub fn as_u32(&self) -> u32 {
179 self.0
180 }
181
182 pub fn as_u64(&self) -> u64 {
184 self.0 as u64
185 }
186}
187
188#[derive(Clone, Debug)]
190pub struct RelocEntry {
191 pub symbol_name: String,
193 pub r_type: RelocType,
195 pub addend: i64,
197}
198
199impl RelocEntry {
200 pub fn with_name(symbol_name: impl Into<String>, r_type: u32) -> Self {
202 Self {
203 symbol_name: symbol_name.into(),
204 r_type: RelocType(r_type),
205 addend: 0,
206 }
207 }
208
209 pub fn new(r_type: u32) -> Self {
211 Self {
212 symbol_name: String::new(),
213 r_type: RelocType(r_type),
214 addend: 0,
215 }
216 }
217
218 pub fn with_addend(mut self, addend: i64) -> Self {
220 self.addend = addend;
221 self
222 }
223
224 pub fn jump_slot(symbol_name: impl Into<String>, arch: crate::Arch) -> Self {
226 Self::with_name(symbol_name, arch.jump_slot_reloc())
227 }
228
229 pub fn glob_dat(symbol_name: impl Into<String>, arch: crate::Arch) -> Self {
231 Self::with_name(symbol_name, arch.glob_dat_reloc())
232 }
233
234 pub fn relative(arch: crate::Arch) -> Self {
236 Self::new(arch.relative_reloc())
237 }
238
239 pub fn irelative(arch: crate::Arch) -> Self {
241 Self::new(arch.irelative_reloc())
242 }
243
244 pub fn copy(symbol_name: impl Into<String>, arch: crate::Arch) -> Self {
246 Self::with_name(symbol_name, arch.copy_reloc())
247 }
248
249 pub fn dtpoff(symbol_name: impl Into<String>, arch: crate::Arch) -> Self {
251 Self::with_name(symbol_name, arch.dtpoff_reloc())
252 }
253
254 pub fn dtpmod(symbol_name: impl Into<String>, arch: crate::Arch) -> Self {
256 Self::with_name(symbol_name, arch.dtpmod_reloc())
257 }
258
259 pub fn abs(symbol_name: impl Into<String>, arch: crate::Arch) -> Self {
261 Self::with_name(symbol_name, arch.abs_reloc())
262 }
263}