1#![allow(deprecated)]
2
3use llvm_sys::object::{
4 LLVMDisposeObjectFile, LLVMDisposeRelocationIterator, LLVMDisposeSectionIterator, LLVMDisposeSymbolIterator,
5 LLVMGetRelocationOffset, LLVMGetRelocationSymbol, LLVMGetRelocationType, LLVMGetRelocationTypeName,
6 LLVMGetRelocationValueString, LLVMGetRelocations, LLVMGetSectionAddress, LLVMGetSectionContents,
7 LLVMGetSectionName, LLVMGetSectionSize, LLVMGetSections, LLVMGetSymbolAddress, LLVMGetSymbolName,
8 LLVMGetSymbolSize, LLVMGetSymbols, LLVMIsRelocationIteratorAtEnd, LLVMIsSectionIteratorAtEnd,
9 LLVMIsSymbolIteratorAtEnd, LLVMMoveToNextRelocation, LLVMMoveToNextSection, LLVMMoveToNextSymbol,
10 LLVMObjectFileRef, LLVMRelocationIteratorRef, LLVMSectionIteratorRef, LLVMSymbolIteratorRef,
11};
12
13use std::ffi::CStr;
14
15#[derive(Debug)]
19pub struct ObjectFile {
20 object_file: LLVMObjectFileRef,
21}
22
23impl ObjectFile {
24 pub unsafe fn new(object_file: LLVMObjectFileRef) -> Self {
25 assert!(!object_file.is_null());
26
27 ObjectFile { object_file }
28 }
29
30 pub fn as_mut_ptr(&self) -> LLVMObjectFileRef {
31 self.object_file
32 }
33
34 pub fn get_sections(&self) -> SectionIterator {
35 let section_iterator = unsafe { LLVMGetSections(self.object_file) };
36
37 unsafe { SectionIterator::new(section_iterator, self.object_file) }
38 }
39
40 pub fn get_symbols(&self) -> SymbolIterator {
41 let symbol_iterator = unsafe { LLVMGetSymbols(self.object_file) };
42
43 unsafe { SymbolIterator::new(symbol_iterator, self.object_file) }
44 }
45}
46
47impl Drop for ObjectFile {
48 fn drop(&mut self) {
49 unsafe { LLVMDisposeObjectFile(self.object_file) }
50 }
51}
52
53#[derive(Debug)]
54pub struct SectionIterator {
55 section_iterator: LLVMSectionIteratorRef,
56 object_file: LLVMObjectFileRef,
57 before_first: bool,
58}
59
60impl SectionIterator {
61 pub unsafe fn new(section_iterator: LLVMSectionIteratorRef, object_file: LLVMObjectFileRef) -> Self {
62 assert!(!section_iterator.is_null());
63 assert!(!object_file.is_null());
64
65 SectionIterator {
66 section_iterator,
67 object_file,
68 before_first: true,
69 }
70 }
71
72 pub fn as_mut_ptr(&self) -> (LLVMSectionIteratorRef, LLVMObjectFileRef) {
73 (self.section_iterator, self.object_file)
74 }
75}
76
77impl Iterator for SectionIterator {
78 type Item = Section;
79
80 fn next(&mut self) -> Option<Self::Item> {
81 if self.before_first {
82 self.before_first = false;
83 } else {
84 unsafe {
85 LLVMMoveToNextSection(self.section_iterator);
86 }
87 }
88
89 let at_end = unsafe { LLVMIsSectionIteratorAtEnd(self.object_file, self.section_iterator) == 1 };
90
91 if at_end {
92 return None;
93 }
94
95 Some(unsafe { Section::new(self.section_iterator, self.object_file) })
96 }
97}
98
99impl Drop for SectionIterator {
100 fn drop(&mut self) {
101 unsafe { LLVMDisposeSectionIterator(self.section_iterator) }
102 }
103}
104
105#[derive(Debug)]
106pub struct Section {
107 section: LLVMSectionIteratorRef,
108 object_file: LLVMObjectFileRef,
109}
110
111impl Section {
112 pub unsafe fn new(section: LLVMSectionIteratorRef, object_file: LLVMObjectFileRef) -> Self {
113 assert!(!section.is_null());
114 assert!(!object_file.is_null());
115
116 Section { section, object_file }
117 }
118
119 pub unsafe fn as_mut_ptr(&self) -> (LLVMSectionIteratorRef, LLVMObjectFileRef) {
120 (self.section, self.object_file)
121 }
122
123 pub fn get_name(&self) -> Option<&CStr> {
124 let name = unsafe { LLVMGetSectionName(self.section) };
125 if !name.is_null() {
126 Some(unsafe { CStr::from_ptr(name) })
127 } else {
128 None
129 }
130 }
131
132 pub fn size(&self) -> u64 {
133 unsafe { LLVMGetSectionSize(self.section) }
134 }
135
136 pub fn get_contents(&self) -> &[u8] {
137 unsafe { std::slice::from_raw_parts(LLVMGetSectionContents(self.section) as *const u8, self.size() as usize) }
138 }
139
140 pub fn get_address(&self) -> u64 {
141 unsafe { LLVMGetSectionAddress(self.section) }
142 }
143
144 pub fn get_relocations(&self) -> RelocationIterator {
145 let relocation_iterator = unsafe { LLVMGetRelocations(self.section) };
146
147 unsafe { RelocationIterator::new(relocation_iterator, self.section, self.object_file) }
148 }
149}
150
151#[derive(Debug)]
152pub struct RelocationIterator {
153 relocation_iterator: LLVMRelocationIteratorRef,
154 section_iterator: LLVMSectionIteratorRef,
155 object_file: LLVMObjectFileRef,
156 before_first: bool,
157}
158
159impl RelocationIterator {
160 pub unsafe fn new(
161 relocation_iterator: LLVMRelocationIteratorRef,
162 section_iterator: LLVMSectionIteratorRef,
163 object_file: LLVMObjectFileRef,
164 ) -> Self {
165 assert!(!relocation_iterator.is_null());
166 assert!(!section_iterator.is_null());
167 assert!(!object_file.is_null());
168
169 RelocationIterator {
170 relocation_iterator,
171 section_iterator,
172 object_file,
173 before_first: true,
174 }
175 }
176
177 pub fn as_mut_ptr(&self) -> (LLVMRelocationIteratorRef, LLVMSectionIteratorRef, LLVMObjectFileRef) {
178 (self.relocation_iterator, self.section_iterator, self.object_file)
179 }
180}
181
182impl Iterator for RelocationIterator {
183 type Item = Relocation;
184
185 fn next(&mut self) -> Option<Self::Item> {
186 if self.before_first {
187 self.before_first = false;
188 } else {
189 unsafe { LLVMMoveToNextRelocation(self.relocation_iterator) }
190 }
191
192 let at_end = unsafe { LLVMIsRelocationIteratorAtEnd(self.section_iterator, self.relocation_iterator) == 1 };
193
194 if at_end {
195 return None;
196 }
197
198 Some(unsafe { Relocation::new(self.relocation_iterator, self.object_file) })
199 }
200}
201
202impl Drop for RelocationIterator {
203 fn drop(&mut self) {
204 unsafe { LLVMDisposeRelocationIterator(self.relocation_iterator) }
205 }
206}
207
208#[derive(Debug)]
209pub struct Relocation {
210 relocation: LLVMRelocationIteratorRef,
211 object_file: LLVMObjectFileRef,
212}
213
214impl Relocation {
215 pub unsafe fn new(relocation: LLVMRelocationIteratorRef, object_file: LLVMObjectFileRef) -> Self {
216 assert!(!relocation.is_null());
217 assert!(!object_file.is_null());
218
219 Relocation {
220 relocation,
221 object_file,
222 }
223 }
224
225 pub fn as_mut_ptr(&self) -> (LLVMRelocationIteratorRef, LLVMObjectFileRef) {
226 (self.relocation, self.object_file)
227 }
228
229 pub fn get_offset(&self) -> u64 {
230 unsafe { LLVMGetRelocationOffset(self.relocation) }
231 }
232
233 pub fn get_symbols(&self) -> SymbolIterator {
234 let symbol_iterator = unsafe {
235 LLVMGetRelocationSymbol(self.relocation)
237 };
238
239 unsafe { SymbolIterator::new(symbol_iterator, self.object_file) }
240 }
241
242 pub fn get_type(&self) -> (u64, &CStr) {
243 let type_int = unsafe { LLVMGetRelocationType(self.relocation) };
244 let type_name = unsafe { CStr::from_ptr(LLVMGetRelocationTypeName(self.relocation)) };
245
246 (type_int, type_name)
247 }
248
249 pub fn get_value(&self) -> &CStr {
250 unsafe { CStr::from_ptr(LLVMGetRelocationValueString(self.relocation)) }
251 }
252}
253
254#[derive(Debug)]
255pub struct SymbolIterator {
256 symbol_iterator: LLVMSymbolIteratorRef,
257 object_file: LLVMObjectFileRef,
258 before_first: bool,
259}
260
261impl SymbolIterator {
262 pub unsafe fn new(symbol_iterator: LLVMSymbolIteratorRef, object_file: LLVMObjectFileRef) -> Self {
263 assert!(!symbol_iterator.is_null());
264 assert!(!object_file.is_null());
265
266 SymbolIterator {
267 symbol_iterator,
268 object_file,
269 before_first: true,
270 }
271 }
272
273 pub fn as_mut_ptr(&self) -> (LLVMSymbolIteratorRef, LLVMObjectFileRef) {
274 (self.symbol_iterator, self.object_file)
275 }
276}
277
278impl Iterator for SymbolIterator {
279 type Item = Symbol;
280
281 fn next(&mut self) -> Option<Self::Item> {
282 if self.before_first {
283 self.before_first = false;
284 } else {
285 unsafe { LLVMMoveToNextSymbol(self.symbol_iterator) }
286 }
287
288 let at_end = unsafe { LLVMIsSymbolIteratorAtEnd(self.object_file, self.symbol_iterator) == 1 };
289
290 if at_end {
291 return None;
292 }
293
294 Some(unsafe { Symbol::new(self.symbol_iterator) })
295 }
296}
297
298impl Drop for SymbolIterator {
299 fn drop(&mut self) {
300 unsafe { LLVMDisposeSymbolIterator(self.symbol_iterator) }
301 }
302}
303
304#[derive(Debug)]
305pub struct Symbol {
306 symbol: LLVMSymbolIteratorRef,
307}
308
309impl Symbol {
310 pub unsafe fn new(symbol: LLVMSymbolIteratorRef) -> Self {
311 assert!(!symbol.is_null());
312
313 Symbol { symbol }
314 }
315
316 pub fn as_mut_ptr(&self) -> LLVMSymbolIteratorRef {
317 self.symbol
318 }
319
320 pub fn get_name(&self) -> Option<&CStr> {
321 let name = unsafe { LLVMGetSymbolName(self.symbol) };
322 if !name.is_null() {
323 Some(unsafe { CStr::from_ptr(name) })
324 } else {
325 None
326 }
327 }
328
329 pub fn size(&self) -> u64 {
330 unsafe { LLVMGetSymbolSize(self.symbol) }
331 }
332
333 pub fn get_address(&self) -> u64 {
334 unsafe { LLVMGetSymbolAddress(self.symbol) }
335 }
336}