goblin_experimental/mach/
relocation.rs1use crate::mach;
26use core::fmt;
27use scroll::{IOread, IOwrite, Pread, Pwrite, SizeWith};
28
29#[derive(Copy, Clone, Pread, Pwrite, IOwrite, SizeWith, IOread)]
31#[repr(C)]
32pub struct RelocationInfo {
33 pub r_address: i32,
35 pub r_info: u32,
38}
39
40pub const SIZEOF_RELOCATION_INFO: usize = 8;
41
42impl RelocationInfo {
43 #[inline]
45 pub fn r_symbolnum(self) -> usize {
46 (self.r_info & 0x00ff_ffffu32) as usize
47 }
48 #[inline]
50 pub fn r_pcrel(self) -> u8 {
51 ((self.r_info & 0x0100_0000u32) >> 24) as u8
52 }
53 #[inline]
55 pub fn r_length(self) -> u8 {
56 ((self.r_info & 0x0600_0000u32) >> 25) as u8
57 }
58 #[inline]
60 pub fn r_extern(self) -> u8 {
61 ((self.r_info & 0x0800_0000) >> 27) as u8
62 }
63 #[inline]
65 pub fn r_type(self) -> u8 {
66 ((self.r_info & 0xf000_0000) >> 28) as u8
67 }
68 #[inline]
70 pub fn is_extern(self) -> bool {
71 self.r_extern() == 1
72 }
73 #[inline]
75 pub fn is_pic(self) -> bool {
76 self.r_pcrel() > 0
77 }
78 pub fn to_str(self, cputype: mach::cputype::CpuType) -> &'static str {
80 reloc_to_str(self.r_type(), cputype)
81 }
82}
83
84pub const R_ABS: u8 = 0;
86
87impl fmt::Debug for RelocationInfo {
88 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
89 f.debug_struct("RelocationInfo")
90 .field("r_address", &format_args!("{:#x}", &self.r_address))
91 .field("r_info", &format_args!("{:#x}", &self.r_info))
92 .field("r_symbolnum", &format_args!("{:#x}", &self.r_symbolnum()))
93 .field("r_pcrel", &(self.r_pcrel()))
94 .field("r_length", &self.r_length())
95 .field("r_extern", &self.r_extern())
96 .field("r_type", &self.r_type())
97 .finish()
98 }
99}
100
101pub type RelocType = u8;
102
103pub const X86_64_RELOC_UNSIGNED: RelocType = 0;
105pub const X86_64_RELOC_SIGNED: RelocType = 1;
107pub const X86_64_RELOC_BRANCH: RelocType = 2;
109pub const X86_64_RELOC_GOT_LOAD: RelocType = 3;
111pub const X86_64_RELOC_GOT: RelocType = 4;
113pub const X86_64_RELOC_SUBTRACTOR: RelocType = 5;
115pub const X86_64_RELOC_SIGNED_1: RelocType = 6;
117pub const X86_64_RELOC_SIGNED_2: RelocType = 7;
119pub const X86_64_RELOC_SIGNED_4: RelocType = 8;
121pub const X86_64_RELOC_TLV: RelocType = 9;
123
124pub const GENERIC_RELOC_VANILLA: RelocType = 0;
126pub const GENERIC_RELOC_PAIR: RelocType = 1;
127pub const GENERIC_RELOC_SECTDIFF: RelocType = 2;
128pub const GENERIC_RELOC_PB_LA_PTR: RelocType = 3;
129pub const GENERIC_RELOC_LOCAL_SECTDIFF: RelocType = 4;
130pub const GENERIC_RELOC_TLV: RelocType = 5;
131
132pub const ARM_RELOC_VANILLA: RelocType = GENERIC_RELOC_VANILLA;
134pub const ARM_RELOC_PAIR: RelocType = GENERIC_RELOC_PAIR;
135pub const ARM_RELOC_SECTDIFF: RelocType = GENERIC_RELOC_SECTDIFF;
136pub const ARM_RELOC_LOCAL_SECTDIFF: RelocType = 3;
137pub const ARM_RELOC_PB_LA_PTR: RelocType = 4;
138pub const ARM_RELOC_BR24: RelocType = 5;
139pub const ARM_THUMB_RELOC_BR22: RelocType = 6;
140pub const ARM_THUMB_32BIT_BRANCH: RelocType = 7;
142pub const ARM_RELOC_HALF: RelocType = 8;
143pub const ARM_RELOC_HALF_SECTDIFF: RelocType = 9;
144
145pub const ARM64_RELOC_UNSIGNED: RelocType = 0;
147pub const ARM64_RELOC_SUBTRACTOR: RelocType = 1;
149pub const ARM64_RELOC_BRANCH26: RelocType = 2;
151pub const ARM64_RELOC_PAGE21: RelocType = 3;
153pub const ARM64_RELOC_PAGEOFF12: RelocType = 4;
155pub const ARM64_RELOC_GOT_LOAD_PAGE21: RelocType = 5;
157pub const ARM64_RELOC_GOT_LOAD_PAGEOFF12: RelocType = 6;
159pub const ARM64_RELOC_POINTER_TO_GOT: RelocType = 7;
161pub const ARM64_RELOC_TLVP_LOAD_PAGE21: RelocType = 8;
163pub const ARM64_RELOC_TLVP_LOAD_PAGEOFF12: RelocType = 9;
165pub const ARM64_RELOC_ADDEND: RelocType = 10;
167
168pub fn reloc_to_str(reloc: RelocType, cputype: mach::cputype::CpuType) -> &'static str {
169 use crate::mach::constants::cputype::*;
170 match cputype {
171 CPU_TYPE_ARM64 | CPU_TYPE_ARM64_32 => match reloc {
172 ARM64_RELOC_UNSIGNED => "ARM64_RELOC_UNSIGNED",
173 ARM64_RELOC_SUBTRACTOR => "ARM64_RELOC_SUBTRACTOR",
174 ARM64_RELOC_BRANCH26 => "ARM64_RELOC_BRANCH26",
175 ARM64_RELOC_PAGE21 => "ARM64_RELOC_PAGE21",
176 ARM64_RELOC_PAGEOFF12 => "ARM64_RELOC_PAGEOFF12",
177 ARM64_RELOC_GOT_LOAD_PAGE21 => "ARM64_RELOC_GOT_LOAD_PAGE21",
178 ARM64_RELOC_GOT_LOAD_PAGEOFF12 => "ARM64_RELOC_GOT_LOAD_PAGEOFF12",
179 ARM64_RELOC_POINTER_TO_GOT => "ARM64_RELOC_POINTER_TO_GOT",
180 ARM64_RELOC_TLVP_LOAD_PAGE21 => "ARM64_RELOC_TLVP_LOAD_PAGE21",
181 ARM64_RELOC_TLVP_LOAD_PAGEOFF12 => "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
182 ARM64_RELOC_ADDEND => "ARM64_RELOC_ADDEND",
183 _ => "UNKNOWN",
184 },
185 CPU_TYPE_X86_64 => match reloc {
186 X86_64_RELOC_UNSIGNED => "X86_64_RELOC_UNSIGNED",
187 X86_64_RELOC_SIGNED => "X86_64_RELOC_SIGNED",
188 X86_64_RELOC_BRANCH => "X86_64_RELOC_BRANCH",
189 X86_64_RELOC_GOT_LOAD => "X86_64_RELOC_GOT_LOAD",
190 X86_64_RELOC_GOT => "X86_64_RELOC_GOT",
191 X86_64_RELOC_SUBTRACTOR => "X86_64_RELOC_SUBTRACTOR",
192 X86_64_RELOC_SIGNED_1 => "X86_64_RELOC_SIGNED_1",
193 X86_64_RELOC_SIGNED_2 => "X86_64_RELOC_SIGNED_2",
194 X86_64_RELOC_SIGNED_4 => "X86_64_RELOC_SIGNED_4",
195 X86_64_RELOC_TLV => "X86_64_RELOC_TLV",
196 _ => "UNKNOWN",
197 },
198 CPU_TYPE_ARM => match reloc {
199 ARM_RELOC_VANILLA => "ARM_RELOC_VANILLA",
200 ARM_RELOC_PAIR => "ARM_RELOC_PAIR",
201 ARM_RELOC_SECTDIFF => "ARM_RELOC_SECTDIFF",
202 ARM_RELOC_LOCAL_SECTDIFF => "ARM_RELOC_LOCAL_SECTDIFF",
203 ARM_RELOC_PB_LA_PTR => "ARM_RELOC_PB_LA_PTR",
204 ARM_RELOC_BR24 => "ARM_RELOC_BR24",
205 ARM_THUMB_RELOC_BR22 => "ARM_THUMB_RELOC_BR22",
206 ARM_THUMB_32BIT_BRANCH => "ARM_THUMB_32BIT_BRANCH",
207 ARM_RELOC_HALF => "ARM_RELOC_HALF",
208 ARM_RELOC_HALF_SECTDIFF => "ARM_RELOC_HALF_SECTDIFF",
209 _ => "UNKNOWN",
210 },
211 CPU_TYPE_X86 => match reloc {
212 GENERIC_RELOC_VANILLA => "GENERIC_RELOC_VANILLA",
213 GENERIC_RELOC_PAIR => "GENERIC_RELOC_PAIR",
214 GENERIC_RELOC_SECTDIFF => "GENERIC_RELOC_SECTDIFF",
215 GENERIC_RELOC_PB_LA_PTR => "GENERIC_RELOC_PB_LA_PTR",
216 GENERIC_RELOC_LOCAL_SECTDIFF => "GENERIC_RELOC_LOCAL_SECTDIFF",
217 GENERIC_RELOC_TLV => "GENERIC_RELOC_TLV",
218 _ => "UNKNOWN",
219 },
220 _ => "BAD_CPUTYPE",
221 }
222}