1 | /// A CPU architecture. |
2 | #[allow (missing_docs)] |
3 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Hash)] |
4 | #[non_exhaustive ] |
5 | pub enum Architecture { |
6 | Unknown, |
7 | Aarch64, |
8 | #[allow (non_camel_case_types)] |
9 | Aarch64_Ilp32, |
10 | Arm, |
11 | Avr, |
12 | Bpf, |
13 | Csky, |
14 | I386, |
15 | X86_64, |
16 | #[allow (non_camel_case_types)] |
17 | X86_64_X32, |
18 | Hexagon, |
19 | LoongArch64, |
20 | Mips, |
21 | Mips64, |
22 | Msp430, |
23 | PowerPc, |
24 | PowerPc64, |
25 | Riscv32, |
26 | Riscv64, |
27 | S390x, |
28 | Sbf, |
29 | Sharc, |
30 | Sparc64, |
31 | Wasm32, |
32 | Wasm64, |
33 | Xtensa, |
34 | } |
35 | |
36 | /// A CPU sub-architecture. |
37 | #[allow (missing_docs)] |
38 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Hash)] |
39 | #[non_exhaustive ] |
40 | pub enum SubArchitecture { |
41 | Arm64E, |
42 | Arm64EC, |
43 | } |
44 | |
45 | impl Architecture { |
46 | /// The size of an address value for this architecture. |
47 | /// |
48 | /// Returns `None` for unknown architectures. |
49 | pub fn address_size(self) -> Option<AddressSize> { |
50 | match self { |
51 | Architecture::Unknown => None, |
52 | Architecture::Aarch64 => Some(AddressSize::U64), |
53 | Architecture::Aarch64_Ilp32 => Some(AddressSize::U32), |
54 | Architecture::Arm => Some(AddressSize::U32), |
55 | Architecture::Avr => Some(AddressSize::U8), |
56 | Architecture::Bpf => Some(AddressSize::U64), |
57 | Architecture::Csky => Some(AddressSize::U32), |
58 | Architecture::I386 => Some(AddressSize::U32), |
59 | Architecture::X86_64 => Some(AddressSize::U64), |
60 | Architecture::X86_64_X32 => Some(AddressSize::U32), |
61 | Architecture::Hexagon => Some(AddressSize::U32), |
62 | Architecture::LoongArch64 => Some(AddressSize::U64), |
63 | Architecture::Mips => Some(AddressSize::U32), |
64 | Architecture::Mips64 => Some(AddressSize::U64), |
65 | Architecture::Msp430 => Some(AddressSize::U16), |
66 | Architecture::PowerPc => Some(AddressSize::U32), |
67 | Architecture::PowerPc64 => Some(AddressSize::U64), |
68 | Architecture::Riscv32 => Some(AddressSize::U32), |
69 | Architecture::Riscv64 => Some(AddressSize::U64), |
70 | Architecture::S390x => Some(AddressSize::U64), |
71 | Architecture::Sbf => Some(AddressSize::U64), |
72 | Architecture::Sharc => Some(AddressSize::U32), |
73 | Architecture::Sparc64 => Some(AddressSize::U64), |
74 | Architecture::Wasm32 => Some(AddressSize::U32), |
75 | Architecture::Wasm64 => Some(AddressSize::U64), |
76 | Architecture::Xtensa => Some(AddressSize::U32), |
77 | } |
78 | } |
79 | } |
80 | |
81 | /// The size of an address value for an architecture. |
82 | /// |
83 | /// This may differ from the address size supported by the file format (such as for COFF). |
84 | #[allow (missing_docs)] |
85 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Hash)] |
86 | #[non_exhaustive ] |
87 | #[repr (u8)] |
88 | pub enum AddressSize { |
89 | U8 = 1, |
90 | U16 = 2, |
91 | U32 = 4, |
92 | U64 = 8, |
93 | } |
94 | |
95 | impl AddressSize { |
96 | /// The size in bytes of an address value. |
97 | #[inline ] |
98 | pub fn bytes(self) -> u8 { |
99 | self as u8 |
100 | } |
101 | } |
102 | |
103 | /// A binary file format. |
104 | #[allow (missing_docs)] |
105 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Hash)] |
106 | #[non_exhaustive ] |
107 | pub enum BinaryFormat { |
108 | Coff, |
109 | Elf, |
110 | MachO, |
111 | Pe, |
112 | Wasm, |
113 | Xcoff, |
114 | } |
115 | |
116 | /// The kind of a section. |
117 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Hash)] |
118 | #[non_exhaustive ] |
119 | pub enum SectionKind { |
120 | /// The section kind is unknown. |
121 | Unknown, |
122 | /// An executable code section. |
123 | /// |
124 | /// Example ELF sections: `.text` |
125 | /// |
126 | /// Example Mach-O sections: `__TEXT/__text` |
127 | Text, |
128 | /// A data section. |
129 | /// |
130 | /// Example ELF sections: `.data` |
131 | /// |
132 | /// Example Mach-O sections: `__DATA/__data` |
133 | Data, |
134 | /// A read only data section. |
135 | /// |
136 | /// Example ELF sections: `.rodata` |
137 | /// |
138 | /// Example Mach-O sections: `__TEXT/__const`, `__DATA/__const`, `__TEXT/__literal4` |
139 | ReadOnlyData, |
140 | /// A read only data section with relocations. |
141 | /// |
142 | /// This is the same as either `Data` or `ReadOnlyData`, depending on the file format. |
143 | /// This value is only used in the API for writing files. It is never returned when reading files. |
144 | ReadOnlyDataWithRel, |
145 | /// A loadable string section. |
146 | /// |
147 | /// Example ELF sections: `.rodata.str` |
148 | /// |
149 | /// Example Mach-O sections: `__TEXT/__cstring` |
150 | ReadOnlyString, |
151 | /// An uninitialized data section. |
152 | /// |
153 | /// Example ELF sections: `.bss` |
154 | /// |
155 | /// Example Mach-O sections: `__DATA/__bss` |
156 | UninitializedData, |
157 | /// An uninitialized common data section. |
158 | /// |
159 | /// Example Mach-O sections: `__DATA/__common` |
160 | Common, |
161 | /// A TLS data section. |
162 | /// |
163 | /// Example ELF sections: `.tdata` |
164 | /// |
165 | /// Example Mach-O sections: `__DATA/__thread_data` |
166 | Tls, |
167 | /// An uninitialized TLS data section. |
168 | /// |
169 | /// Example ELF sections: `.tbss` |
170 | /// |
171 | /// Example Mach-O sections: `__DATA/__thread_bss` |
172 | UninitializedTls, |
173 | /// A TLS variables section. |
174 | /// |
175 | /// This contains TLS variable structures, rather than the variable initializers. |
176 | /// |
177 | /// Example Mach-O sections: `__DATA/__thread_vars` |
178 | TlsVariables, |
179 | /// A non-loadable string section. |
180 | /// |
181 | /// Example ELF sections: `.comment`, `.debug_str` |
182 | OtherString, |
183 | /// Some other non-loadable section. |
184 | /// |
185 | /// Example ELF sections: `.debug_info` |
186 | Other, |
187 | /// Debug information. |
188 | /// |
189 | /// Example Mach-O sections: `__DWARF/__debug_info` |
190 | Debug, |
191 | /// Information for the linker. |
192 | /// |
193 | /// Example COFF sections: `.drectve` |
194 | Linker, |
195 | /// ELF note section. |
196 | Note, |
197 | /// Metadata such as symbols or relocations. |
198 | /// |
199 | /// Example ELF sections: `.symtab`, `.strtab`, `.group` |
200 | Metadata, |
201 | /// Some other ELF section type. |
202 | /// |
203 | /// This is the `sh_type` field in the section header. |
204 | /// The meaning may be dependent on the architecture. |
205 | Elf(u32), |
206 | } |
207 | |
208 | impl SectionKind { |
209 | /// Return true if this section contains zerofill data. |
210 | pub fn is_bss(self) -> bool { |
211 | self == SectionKind::UninitializedData |
212 | || self == SectionKind::UninitializedTls |
213 | || self == SectionKind::Common |
214 | } |
215 | } |
216 | |
217 | /// The selection kind for a COMDAT section group. |
218 | /// |
219 | /// This determines the way in which the linker resolves multiple definitions of the COMDAT |
220 | /// sections. |
221 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Hash)] |
222 | #[non_exhaustive ] |
223 | pub enum ComdatKind { |
224 | /// The selection kind is unknown. |
225 | Unknown, |
226 | /// Multiple definitions are allowed. |
227 | /// |
228 | /// An arbitrary definition is selected, and the rest are removed. |
229 | /// |
230 | /// This is the only supported selection kind for ELF. |
231 | Any, |
232 | /// Multiple definitions are not allowed. |
233 | /// |
234 | /// This is used to group sections without allowing duplicates. |
235 | NoDuplicates, |
236 | /// Multiple definitions must have the same size. |
237 | /// |
238 | /// An arbitrary definition is selected, and the rest are removed. |
239 | SameSize, |
240 | /// Multiple definitions must match exactly. |
241 | /// |
242 | /// An arbitrary definition is selected, and the rest are removed. |
243 | ExactMatch, |
244 | /// Multiple definitions are allowed, and the largest is selected. |
245 | /// |
246 | /// An arbitrary definition with the largest size is selected, and the rest are removed. |
247 | Largest, |
248 | /// Multiple definitions are allowed, and the newest is selected. |
249 | Newest, |
250 | } |
251 | |
252 | /// The kind of a symbol. |
253 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Hash)] |
254 | #[non_exhaustive ] |
255 | pub enum SymbolKind { |
256 | /// The symbol kind is unknown. |
257 | Unknown, |
258 | /// The symbol is a null placeholder. |
259 | Null, |
260 | /// The symbol is for executable code. |
261 | Text, |
262 | /// The symbol is for a data object. |
263 | Data, |
264 | /// The symbol is for a section. |
265 | Section, |
266 | /// The symbol is the name of a file. It precedes symbols within that file. |
267 | File, |
268 | /// The symbol is for a code label. |
269 | Label, |
270 | /// The symbol is for a thread local storage entity. |
271 | Tls, |
272 | } |
273 | |
274 | /// A symbol scope. |
275 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Hash)] |
276 | pub enum SymbolScope { |
277 | /// Unknown scope. |
278 | Unknown, |
279 | /// Symbol is visible to the compilation unit. |
280 | Compilation, |
281 | /// Symbol is visible to the static linkage unit. |
282 | Linkage, |
283 | /// Symbol is visible to dynamically linked objects. |
284 | Dynamic, |
285 | } |
286 | |
287 | /// The operation used to calculate the result of the relocation. |
288 | /// |
289 | /// The relocation descriptions use the following definitions. Note that |
290 | /// these definitions probably don't match any ELF ABI. |
291 | /// |
292 | /// * A - The value of the addend. |
293 | /// * G - The address of the symbol's entry within the global offset table. |
294 | /// * L - The address of the symbol's entry within the procedure linkage table. |
295 | /// * P - The address of the place of the relocation. |
296 | /// * S - The address of the symbol. |
297 | /// * GotBase - The address of the global offset table. |
298 | /// * Image - The base address of the image. |
299 | /// * Section - The address of the section containing the symbol. |
300 | /// |
301 | /// 'XxxRelative' means 'Xxx + A - P'. 'XxxOffset' means 'S + A - Xxx'. |
302 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Hash)] |
303 | #[non_exhaustive ] |
304 | pub enum RelocationKind { |
305 | /// S + A |
306 | Absolute, |
307 | /// S + A - P |
308 | Relative, |
309 | /// G + A - GotBase |
310 | Got, |
311 | /// G + A - P |
312 | GotRelative, |
313 | /// GotBase + A - P |
314 | GotBaseRelative, |
315 | /// S + A - GotBase |
316 | GotBaseOffset, |
317 | /// L + A - P |
318 | PltRelative, |
319 | /// S + A - Image |
320 | ImageOffset, |
321 | /// S + A - Section |
322 | SectionOffset, |
323 | /// The index of the section containing the symbol. |
324 | SectionIndex, |
325 | /// Some other ELF relocation. The value is dependent on the architecture. |
326 | Elf(u32), |
327 | /// Some other Mach-O relocation. The value is dependent on the architecture. |
328 | MachO { |
329 | /// The relocation type. |
330 | value: u8, |
331 | /// Whether the relocation is relative to the place. |
332 | relative: bool, |
333 | }, |
334 | /// Some other COFF relocation. The value is dependent on the architecture. |
335 | Coff(u16), |
336 | /// Some other XCOFF relocation. |
337 | Xcoff(u8), |
338 | } |
339 | |
340 | /// Information about how the result of the relocation operation is encoded in the place. |
341 | /// |
342 | /// This is usually architecture specific, such as specifying an addressing mode or |
343 | /// a specific instruction. |
344 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Hash)] |
345 | #[non_exhaustive ] |
346 | pub enum RelocationEncoding { |
347 | /// Generic encoding. |
348 | Generic, |
349 | |
350 | /// x86 sign extension at runtime. |
351 | /// |
352 | /// Used with `RelocationKind::Absolute`. |
353 | X86Signed, |
354 | /// x86 rip-relative addressing. |
355 | /// |
356 | /// The `RelocationKind` must be PC relative. |
357 | X86RipRelative, |
358 | /// x86 rip-relative addressing in movq instruction. |
359 | /// |
360 | /// The `RelocationKind` must be PC relative. |
361 | X86RipRelativeMovq, |
362 | /// x86 branch instruction. |
363 | /// |
364 | /// The `RelocationKind` must be PC relative. |
365 | X86Branch, |
366 | |
367 | /// s390x PC-relative offset shifted right by one bit. |
368 | /// |
369 | /// The `RelocationKind` must be PC relative. |
370 | S390xDbl, |
371 | |
372 | /// AArch64 call target. |
373 | /// |
374 | /// The `RelocationKind` must be PC relative. |
375 | AArch64Call, |
376 | |
377 | /// LoongArch branch offset with two trailing zeros. |
378 | /// |
379 | /// The `RelocationKind` must be PC relative. |
380 | LoongArchBranch, |
381 | |
382 | /// SHARC+ 48-bit Type A instruction |
383 | /// |
384 | /// Represents these possible variants, each with a corresponding |
385 | /// `R_SHARC_*` constant: |
386 | /// |
387 | /// * 24-bit absolute address |
388 | /// * 32-bit absolute address |
389 | /// * 6-bit relative address |
390 | /// * 24-bit relative address |
391 | /// * 6-bit absolute address in the immediate value field |
392 | /// * 16-bit absolute address in the immediate value field |
393 | SharcTypeA, |
394 | |
395 | /// SHARC+ 32-bit Type B instruction |
396 | /// |
397 | /// Represents these possible variants, each with a corresponding |
398 | /// `R_SHARC_*` constant: |
399 | /// |
400 | /// * 6-bit absolute address in the immediate value field |
401 | /// * 7-bit absolute address in the immediate value field |
402 | /// * 16-bit absolute address |
403 | /// * 6-bit relative address |
404 | SharcTypeB, |
405 | } |
406 | |
407 | /// File flags that are specific to each file format. |
408 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Hash)] |
409 | #[non_exhaustive ] |
410 | pub enum FileFlags { |
411 | /// No file flags. |
412 | None, |
413 | /// ELF file flags. |
414 | Elf { |
415 | /// `os_abi` field in the ELF file header. |
416 | os_abi: u8, |
417 | /// `abi_version` field in the ELF file header. |
418 | abi_version: u8, |
419 | /// `e_flags` field in the ELF file header. |
420 | e_flags: u32, |
421 | }, |
422 | /// Mach-O file flags. |
423 | MachO { |
424 | /// `flags` field in the Mach-O file header. |
425 | flags: u32, |
426 | }, |
427 | /// COFF file flags. |
428 | Coff { |
429 | /// `Characteristics` field in the COFF file header. |
430 | characteristics: u16, |
431 | }, |
432 | /// XCOFF file flags. |
433 | Xcoff { |
434 | /// `f_flags` field in the XCOFF file header. |
435 | f_flags: u16, |
436 | }, |
437 | } |
438 | |
439 | /// Segment flags that are specific to each file format. |
440 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Hash)] |
441 | #[non_exhaustive ] |
442 | pub enum SegmentFlags { |
443 | /// No segment flags. |
444 | None, |
445 | /// ELF segment flags. |
446 | Elf { |
447 | /// `p_flags` field in the segment header. |
448 | p_flags: u32, |
449 | }, |
450 | /// Mach-O segment flags. |
451 | MachO { |
452 | /// `flags` field in the segment header. |
453 | flags: u32, |
454 | /// `maxprot` field in the segment header. |
455 | maxprot: u32, |
456 | /// `initprot` field in the segment header. |
457 | initprot: u32, |
458 | }, |
459 | /// COFF segment flags. |
460 | Coff { |
461 | /// `Characteristics` field in the segment header. |
462 | characteristics: u32, |
463 | }, |
464 | } |
465 | |
466 | /// Section flags that are specific to each file format. |
467 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Hash)] |
468 | #[non_exhaustive ] |
469 | pub enum SectionFlags { |
470 | /// No section flags. |
471 | None, |
472 | /// ELF section flags. |
473 | Elf { |
474 | /// `sh_flags` field in the section header. |
475 | sh_flags: u64, |
476 | }, |
477 | /// Mach-O section flags. |
478 | MachO { |
479 | /// `flags` field in the section header. |
480 | flags: u32, |
481 | }, |
482 | /// COFF section flags. |
483 | Coff { |
484 | /// `Characteristics` field in the section header. |
485 | characteristics: u32, |
486 | }, |
487 | /// XCOFF section flags. |
488 | Xcoff { |
489 | /// `s_flags` field in the section header. |
490 | s_flags: u32, |
491 | }, |
492 | } |
493 | |
494 | /// Symbol flags that are specific to each file format. |
495 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Hash)] |
496 | #[non_exhaustive ] |
497 | pub enum SymbolFlags<Section, Symbol> { |
498 | /// No symbol flags. |
499 | None, |
500 | /// ELF symbol flags. |
501 | Elf { |
502 | /// `st_info` field in the ELF symbol. |
503 | st_info: u8, |
504 | /// `st_other` field in the ELF symbol. |
505 | st_other: u8, |
506 | }, |
507 | /// Mach-O symbol flags. |
508 | MachO { |
509 | /// `n_desc` field in the Mach-O symbol. |
510 | n_desc: u16, |
511 | }, |
512 | /// COFF flags for a section symbol. |
513 | CoffSection { |
514 | /// `Selection` field in the auxiliary symbol for the section. |
515 | selection: u8, |
516 | /// `Number` field in the auxiliary symbol for the section. |
517 | associative_section: Option<Section>, |
518 | }, |
519 | /// XCOFF symbol flags. |
520 | Xcoff { |
521 | /// `n_sclass` field in the XCOFF symbol. |
522 | n_sclass: u8, |
523 | /// `x_smtyp` field in the CSECT auxiliary symbol. |
524 | /// |
525 | /// Only valid if `n_sclass` is `C_EXT`, `C_WEAKEXT`, or `C_HIDEXT`. |
526 | x_smtyp: u8, |
527 | /// `x_smclas` field in the CSECT auxiliary symbol. |
528 | /// |
529 | /// Only valid if `n_sclass` is `C_EXT`, `C_WEAKEXT`, or `C_HIDEXT`. |
530 | x_smclas: u8, |
531 | /// The containing csect for the symbol. |
532 | /// |
533 | /// Only valid if `x_smtyp` is `XTY_LD`. |
534 | containing_csect: Option<Symbol>, |
535 | }, |
536 | } |
537 | |