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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
use crate::mach;
use core::fmt;
use scroll::{IOread, IOwrite, Pread, Pwrite, SizeWith};
#[derive(Copy, Clone, Pread, Pwrite, IOwrite, SizeWith, IOread)]
#[repr(C)]
pub struct RelocationInfo {
pub r_address: i32,
pub r_info: u32,
}
pub const SIZEOF_RELOCATION_INFO: usize = 8;
impl RelocationInfo {
#[inline]
pub fn r_symbolnum(self) -> usize {
(self.r_info & 0x00ff_ffffu32) as usize
}
#[inline]
pub fn r_pcrel(self) -> u8 {
((self.r_info & 0x0100_0000u32) >> 24) as u8
}
#[inline]
pub fn r_length(self) -> u8 {
((self.r_info & 0x0600_0000u32) >> 25) as u8
}
#[inline]
pub fn r_extern(self) -> u8 {
((self.r_info & 0x0800_0000) >> 27) as u8
}
#[inline]
pub fn r_type(self) -> u8 {
((self.r_info & 0xf000_0000) >> 28) as u8
}
#[inline]
pub fn is_extern(self) -> bool {
self.r_extern() == 1
}
#[inline]
pub fn is_pic(self) -> bool {
self.r_pcrel() > 0
}
pub fn to_str(self, cputype: mach::cputype::CpuType) -> &'static str {
reloc_to_str(self.r_type(), cputype)
}
}
pub const R_ABS: u8 = 0;
impl fmt::Debug for RelocationInfo {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("RelocationInfo")
.field("r_address", &format_args!("{:#x}", &self.r_address))
.field("r_info", &format_args!("{:#x}", &self.r_info))
.field("r_symbolnum", &format_args!("{:#x}", &self.r_symbolnum()))
.field("r_pcrel", &(self.r_pcrel()))
.field("r_length", &self.r_length())
.field("r_extern", &self.r_extern())
.field("r_type", &self.r_type())
.finish()
}
}
pub type RelocType = u8;
pub const X86_64_RELOC_UNSIGNED: RelocType = 0;
pub const X86_64_RELOC_SIGNED: RelocType = 1;
pub const X86_64_RELOC_BRANCH: RelocType = 2;
pub const X86_64_RELOC_GOT_LOAD: RelocType = 3;
pub const X86_64_RELOC_GOT: RelocType = 4;
pub const X86_64_RELOC_SUBTRACTOR: RelocType = 5;
pub const X86_64_RELOC_SIGNED_1: RelocType = 6;
pub const X86_64_RELOC_SIGNED_2: RelocType = 7;
pub const X86_64_RELOC_SIGNED_4: RelocType = 8;
pub const X86_64_RELOC_TLV: RelocType = 9;
pub const GENERIC_RELOC_VANILLA: RelocType = 0;
pub const GENERIC_RELOC_PAIR: RelocType = 1;
pub const GENERIC_RELOC_SECTDIFF: RelocType = 2;
pub const GENERIC_RELOC_PB_LA_PTR: RelocType = 3;
pub const GENERIC_RELOC_LOCAL_SECTDIFF: RelocType = 4;
pub const GENERIC_RELOC_TLV: RelocType = 5;
pub const ARM_RELOC_VANILLA: RelocType = GENERIC_RELOC_VANILLA;
pub const ARM_RELOC_PAIR: RelocType = GENERIC_RELOC_PAIR;
pub const ARM_RELOC_SECTDIFF: RelocType = GENERIC_RELOC_SECTDIFF;
pub const ARM_RELOC_LOCAL_SECTDIFF: RelocType = 3;
pub const ARM_RELOC_PB_LA_PTR: RelocType = 4;
pub const ARM_RELOC_BR24: RelocType = 5;
pub const ARM_THUMB_RELOC_BR22: RelocType = 6;
pub const ARM_THUMB_32BIT_BRANCH: RelocType = 7;
pub const ARM_RELOC_HALF: RelocType = 8;
pub const ARM_RELOC_HALF_SECTDIFF: RelocType = 9;
pub const ARM64_RELOC_UNSIGNED: RelocType = 0;
pub const ARM64_RELOC_SUBTRACTOR: RelocType = 1;
pub const ARM64_RELOC_BRANCH26: RelocType = 2;
pub const ARM64_RELOC_PAGE21: RelocType = 3;
pub const ARM64_RELOC_PAGEOFF12: RelocType = 4;
pub const ARM64_RELOC_GOT_LOAD_PAGE21: RelocType = 5;
pub const ARM64_RELOC_GOT_LOAD_PAGEOFF12: RelocType = 6;
pub const ARM64_RELOC_POINTER_TO_GOT: RelocType = 7;
pub const ARM64_RELOC_TLVP_LOAD_PAGE21: RelocType = 8;
pub const ARM64_RELOC_TLVP_LOAD_PAGEOFF12: RelocType = 9;
pub const ARM64_RELOC_ADDEND: RelocType = 10;
pub fn reloc_to_str(reloc: RelocType, cputype: mach::cputype::CpuType) -> &'static str {
use crate::mach::constants::cputype::*;
match cputype {
CPU_TYPE_ARM64 | CPU_TYPE_ARM64_32 => match reloc {
ARM64_RELOC_UNSIGNED => "ARM64_RELOC_UNSIGNED",
ARM64_RELOC_SUBTRACTOR => "ARM64_RELOC_SUBTRACTOR",
ARM64_RELOC_BRANCH26 => "ARM64_RELOC_BRANCH26",
ARM64_RELOC_PAGE21 => "ARM64_RELOC_PAGE21",
ARM64_RELOC_PAGEOFF12 => "ARM64_RELOC_PAGEOFF12",
ARM64_RELOC_GOT_LOAD_PAGE21 => "ARM64_RELOC_GOT_LOAD_PAGE21",
ARM64_RELOC_GOT_LOAD_PAGEOFF12 => "ARM64_RELOC_GOT_LOAD_PAGEOFF12",
ARM64_RELOC_POINTER_TO_GOT => "ARM64_RELOC_POINTER_TO_GOT",
ARM64_RELOC_TLVP_LOAD_PAGE21 => "ARM64_RELOC_TLVP_LOAD_PAGE21",
ARM64_RELOC_TLVP_LOAD_PAGEOFF12 => "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
ARM64_RELOC_ADDEND => "ARM64_RELOC_ADDEND",
_ => "UNKNOWN",
},
CPU_TYPE_X86_64 => match reloc {
X86_64_RELOC_UNSIGNED => "X86_64_RELOC_UNSIGNED",
X86_64_RELOC_SIGNED => "X86_64_RELOC_SIGNED",
X86_64_RELOC_BRANCH => "X86_64_RELOC_BRANCH",
X86_64_RELOC_GOT_LOAD => "X86_64_RELOC_GOT_LOAD",
X86_64_RELOC_GOT => "X86_64_RELOC_GOT",
X86_64_RELOC_SUBTRACTOR => "X86_64_RELOC_SUBTRACTOR",
X86_64_RELOC_SIGNED_1 => "X86_64_RELOC_SIGNED_1",
X86_64_RELOC_SIGNED_2 => "X86_64_RELOC_SIGNED_2",
X86_64_RELOC_SIGNED_4 => "X86_64_RELOC_SIGNED_4",
X86_64_RELOC_TLV => "X86_64_RELOC_TLV",
_ => "UNKNOWN",
},
CPU_TYPE_ARM => match reloc {
ARM_RELOC_VANILLA => "ARM_RELOC_VANILLA",
ARM_RELOC_PAIR => "ARM_RELOC_PAIR",
ARM_RELOC_SECTDIFF => "ARM_RELOC_SECTDIFF",
ARM_RELOC_LOCAL_SECTDIFF => "ARM_RELOC_LOCAL_SECTDIFF",
ARM_RELOC_PB_LA_PTR => "ARM_RELOC_PB_LA_PTR",
ARM_RELOC_BR24 => "ARM_RELOC_BR24",
ARM_THUMB_RELOC_BR22 => "ARM_THUMB_RELOC_BR22",
ARM_THUMB_32BIT_BRANCH => "ARM_THUMB_32BIT_BRANCH",
ARM_RELOC_HALF => "ARM_RELOC_HALF",
ARM_RELOC_HALF_SECTDIFF => "ARM_RELOC_HALF_SECTDIFF",
_ => "UNKNOWN",
},
CPU_TYPE_X86 => match reloc {
GENERIC_RELOC_VANILLA => "GENERIC_RELOC_VANILLA",
GENERIC_RELOC_PAIR => "GENERIC_RELOC_PAIR",
GENERIC_RELOC_SECTDIFF => "GENERIC_RELOC_SECTDIFF",
GENERIC_RELOC_PB_LA_PTR => "GENERIC_RELOC_PB_LA_PTR",
GENERIC_RELOC_LOCAL_SECTDIFF => "GENERIC_RELOC_LOCAL_SECTDIFF",
GENERIC_RELOC_TLV => "GENERIC_RELOC_TLV",
_ => "UNKNOWN",
},
_ => "BAD_CPUTYPE",
}
}