1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
use crate::result::*;
use core::ptr;
pub mod rc;
#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
#[repr(i64)]
pub enum Tag {
#[default]
Invalid = 0,
Needed = 1,
PltRelSize = 2,
Hash = 4,
StrTab = 5,
SymTab = 6,
RelaOffset = 7,
RelaSize = 8,
RelaEntrySize = 9,
SymEnt = 11,
RelOffset = 17,
RelSize = 18,
RelEntrySize = 19,
PltRel = 20,
JmpRel = 23,
InitArray = 25,
FiniArray = 26,
InitArraySize = 27,
FiniArraySize = 28,
RelaCount = 0x6FFFFFF9
}
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
#[repr(u32)]
pub enum RelocationType {
AArch64Abs64 = 257,
AArch64GlobDat = 1025,
AArch64JumpSlot = 1026,
AArch64Relative = 1027
}
#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
#[repr(C)]
pub struct Dyn {
pub tag: Tag,
pub val_ptr: u64,
}
impl Dyn {
pub fn find_value(&self, tag: Tag) -> Result<u64> {
unsafe {
let mut found: *const u64 = ptr::null();
let mut self_ptr = self as *const Self;
while (*self_ptr).tag != Tag::Invalid {
if (*self_ptr).tag == tag {
result_return_unless!(found.is_null(), rc::ResultDuplicatedDtEntry);
found = &(*self_ptr).val_ptr;
}
self_ptr = self_ptr.offset(1);
}
result_return_if!(found.is_null(), rc::ResultMissingDtEntry);
Ok(*found)
}
}
}
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
#[repr(C)]
pub struct InfoSymbol {
pub relocation_type: RelocationType,
pub symbol: u32,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub union Info {
pub value: u64,
pub symbol: InfoSymbol,
}
#[derive(Copy, Clone)]
#[repr(C)]
pub struct Rela {
pub offset: u64,
pub info: Info,
pub addend: i64,
}