1use alloc::fmt;
2use alloc::vec::Vec;
3use core::marker::PhantomData;
4
5#[allow(unused_imports)] use crate::endian::Endianness;
7#[cfg(feature = "coff")]
8use crate::read::coff;
9#[cfg(feature = "elf")]
10use crate::read::elf;
11#[cfg(feature = "macho")]
12use crate::read::macho;
13#[cfg(feature = "pe")]
14use crate::read::pe;
15#[cfg(feature = "wasm")]
16use crate::read::wasm;
17#[cfg(feature = "xcoff")]
18use crate::read::xcoff;
19use crate::read::{
20 self, Architecture, BinaryFormat, CodeView, ComdatKind, CompressedData, CompressedFileRange,
21 Error, Export, FileFlags, FileKind, Import, Object, ObjectComdat, ObjectKind, ObjectMap,
22 ObjectSection, ObjectSegment, ObjectSymbol, ObjectSymbolTable, Permissions, ReadRef,
23 Relocation, RelocationMap, Result, SectionFlags, SectionIndex, SectionKind, SegmentFlags,
24 SubArchitecture, SymbolFlags, SymbolIndex, SymbolKind, SymbolMap, SymbolMapName, SymbolScope,
25 SymbolSection,
26};
27
28macro_rules! with_inner {
32 ($inner:expr, $enum:ident, | $var:ident | $body:expr) => {
33 match $inner {
34 #[cfg(feature = "coff")]
35 $enum::Coff(ref $var) => $body,
36 #[cfg(feature = "coff")]
37 $enum::CoffBig(ref $var) => $body,
38 #[cfg(feature = "elf")]
39 $enum::Elf32(ref $var) => $body,
40 #[cfg(feature = "elf")]
41 $enum::Elf64(ref $var) => $body,
42 #[cfg(feature = "macho")]
43 $enum::MachO32(ref $var) => $body,
44 #[cfg(feature = "macho")]
45 $enum::MachO64(ref $var) => $body,
46 #[cfg(feature = "pe")]
47 $enum::Pe32(ref $var) => $body,
48 #[cfg(feature = "pe")]
49 $enum::Pe64(ref $var) => $body,
50 #[cfg(feature = "wasm")]
51 $enum::Wasm(ref $var) => $body,
52 #[cfg(feature = "xcoff")]
53 $enum::Xcoff32(ref $var) => $body,
54 #[cfg(feature = "xcoff")]
55 $enum::Xcoff64(ref $var) => $body,
56 }
57 };
58}
59
60macro_rules! with_inner_mut {
61 ($inner:expr, $enum:ident, | $var:ident | $body:expr) => {
62 match $inner {
63 #[cfg(feature = "coff")]
64 $enum::Coff(ref mut $var) => $body,
65 #[cfg(feature = "coff")]
66 $enum::CoffBig(ref mut $var) => $body,
67 #[cfg(feature = "elf")]
68 $enum::Elf32(ref mut $var) => $body,
69 #[cfg(feature = "elf")]
70 $enum::Elf64(ref mut $var) => $body,
71 #[cfg(feature = "macho")]
72 $enum::MachO32(ref mut $var) => $body,
73 #[cfg(feature = "macho")]
74 $enum::MachO64(ref mut $var) => $body,
75 #[cfg(feature = "pe")]
76 $enum::Pe32(ref mut $var) => $body,
77 #[cfg(feature = "pe")]
78 $enum::Pe64(ref mut $var) => $body,
79 #[cfg(feature = "wasm")]
80 $enum::Wasm(ref mut $var) => $body,
81 #[cfg(feature = "xcoff")]
82 $enum::Xcoff32(ref mut $var) => $body,
83 #[cfg(feature = "xcoff")]
84 $enum::Xcoff64(ref mut $var) => $body,
85 }
86 };
87}
88
89macro_rules! map_inner {
91 ($inner:expr, $from:ident, $to:ident, | $var:ident | $body:expr) => {
92 match $inner {
93 #[cfg(feature = "coff")]
94 $from::Coff(ref $var) => $to::Coff($body),
95 #[cfg(feature = "coff")]
96 $from::CoffBig(ref $var) => $to::CoffBig($body),
97 #[cfg(feature = "elf")]
98 $from::Elf32(ref $var) => $to::Elf32($body),
99 #[cfg(feature = "elf")]
100 $from::Elf64(ref $var) => $to::Elf64($body),
101 #[cfg(feature = "macho")]
102 $from::MachO32(ref $var) => $to::MachO32($body),
103 #[cfg(feature = "macho")]
104 $from::MachO64(ref $var) => $to::MachO64($body),
105 #[cfg(feature = "pe")]
106 $from::Pe32(ref $var) => $to::Pe32($body),
107 #[cfg(feature = "pe")]
108 $from::Pe64(ref $var) => $to::Pe64($body),
109 #[cfg(feature = "wasm")]
110 $from::Wasm(ref $var) => $to::Wasm($body),
111 #[cfg(feature = "xcoff")]
112 $from::Xcoff32(ref $var) => $to::Xcoff32($body),
113 #[cfg(feature = "xcoff")]
114 $from::Xcoff64(ref $var) => $to::Xcoff64($body),
115 }
116 };
117}
118
119macro_rules! map_inner_option {
121 ($inner:expr, $from:ident, $to:ident, | $var:ident | $body:expr) => {
122 match $inner {
123 #[cfg(feature = "coff")]
124 $from::Coff(ref $var) => $body.map($to::Coff),
125 #[cfg(feature = "coff")]
126 $from::CoffBig(ref $var) => $body.map($to::CoffBig),
127 #[cfg(feature = "elf")]
128 $from::Elf32(ref $var) => $body.map($to::Elf32),
129 #[cfg(feature = "elf")]
130 $from::Elf64(ref $var) => $body.map($to::Elf64),
131 #[cfg(feature = "macho")]
132 $from::MachO32(ref $var) => $body.map($to::MachO32),
133 #[cfg(feature = "macho")]
134 $from::MachO64(ref $var) => $body.map($to::MachO64),
135 #[cfg(feature = "pe")]
136 $from::Pe32(ref $var) => $body.map($to::Pe32),
137 #[cfg(feature = "pe")]
138 $from::Pe64(ref $var) => $body.map($to::Pe64),
139 #[cfg(feature = "wasm")]
140 $from::Wasm(ref $var) => $body.map($to::Wasm),
141 #[cfg(feature = "xcoff")]
142 $from::Xcoff32(ref $var) => $body.map($to::Xcoff32),
143 #[cfg(feature = "xcoff")]
144 $from::Xcoff64(ref $var) => $body.map($to::Xcoff64),
145 }
146 };
147}
148
149macro_rules! map_inner_option_mut {
150 ($inner:expr, $from:ident, $to:ident, | $var:ident | $body:expr) => {
151 match $inner {
152 #[cfg(feature = "coff")]
153 $from::Coff(ref mut $var) => $body.map($to::Coff),
154 #[cfg(feature = "coff")]
155 $from::CoffBig(ref mut $var) => $body.map($to::CoffBig),
156 #[cfg(feature = "elf")]
157 $from::Elf32(ref mut $var) => $body.map($to::Elf32),
158 #[cfg(feature = "elf")]
159 $from::Elf64(ref mut $var) => $body.map($to::Elf64),
160 #[cfg(feature = "macho")]
161 $from::MachO32(ref mut $var) => $body.map($to::MachO32),
162 #[cfg(feature = "macho")]
163 $from::MachO64(ref mut $var) => $body.map($to::MachO64),
164 #[cfg(feature = "pe")]
165 $from::Pe32(ref mut $var) => $body.map($to::Pe32),
166 #[cfg(feature = "pe")]
167 $from::Pe64(ref mut $var) => $body.map($to::Pe64),
168 #[cfg(feature = "wasm")]
169 $from::Wasm(ref mut $var) => $body.map($to::Wasm),
170 #[cfg(feature = "xcoff")]
171 $from::Xcoff32(ref mut $var) => $body.map($to::Xcoff32),
172 #[cfg(feature = "xcoff")]
173 $from::Xcoff64(ref mut $var) => $body.map($to::Xcoff64),
174 }
175 };
176}
177
178macro_rules! next_inner {
180 ($inner:expr, $from:ident, $to:ident) => {
181 match $inner {
182 #[cfg(feature = "coff")]
183 $from::Coff(ref mut iter) => iter.next().map($to::Coff),
184 #[cfg(feature = "coff")]
185 $from::CoffBig(ref mut iter) => iter.next().map($to::CoffBig),
186 #[cfg(feature = "elf")]
187 $from::Elf32(ref mut iter) => iter.next().map($to::Elf32),
188 #[cfg(feature = "elf")]
189 $from::Elf64(ref mut iter) => iter.next().map($to::Elf64),
190 #[cfg(feature = "macho")]
191 $from::MachO32(ref mut iter) => iter.next().map($to::MachO32),
192 #[cfg(feature = "macho")]
193 $from::MachO64(ref mut iter) => iter.next().map($to::MachO64),
194 #[cfg(feature = "pe")]
195 $from::Pe32(ref mut iter) => iter.next().map($to::Pe32),
196 #[cfg(feature = "pe")]
197 $from::Pe64(ref mut iter) => iter.next().map($to::Pe64),
198 #[cfg(feature = "wasm")]
199 $from::Wasm(ref mut iter) => iter.next().map($to::Wasm),
200 #[cfg(feature = "xcoff")]
201 $from::Xcoff32(ref mut iter) => iter.next().map($to::Xcoff32),
202 #[cfg(feature = "xcoff")]
203 $from::Xcoff64(ref mut iter) => iter.next().map($to::Xcoff64),
204 }
205 };
206}
207
208#[derive(Debug)]
212#[non_exhaustive]
213#[allow(missing_docs)]
214pub enum File<'data, R: ReadRef<'data> = &'data [u8]> {
215 #[cfg(feature = "coff")]
216 Coff(coff::CoffFile<'data, R>),
217 #[cfg(feature = "coff")]
218 CoffBig(coff::CoffBigFile<'data, R>),
219 #[cfg(feature = "elf")]
220 Elf32(elf::ElfFile32<'data, Endianness, R>),
221 #[cfg(feature = "elf")]
222 Elf64(elf::ElfFile64<'data, Endianness, R>),
223 #[cfg(feature = "macho")]
224 MachO32(macho::MachOFile32<'data, Endianness, R>),
225 #[cfg(feature = "macho")]
226 MachO64(macho::MachOFile64<'data, Endianness, R>),
227 #[cfg(feature = "pe")]
228 Pe32(pe::PeFile32<'data, R>),
229 #[cfg(feature = "pe")]
230 Pe64(pe::PeFile64<'data, R>),
231 #[cfg(feature = "wasm")]
232 Wasm(wasm::WasmFile<'data, R>),
233 #[cfg(feature = "xcoff")]
234 Xcoff32(xcoff::XcoffFile32<'data, R>),
235 #[cfg(feature = "xcoff")]
236 Xcoff64(xcoff::XcoffFile64<'data, R>),
237}
238
239impl<'data, R: ReadRef<'data>> File<'data, R> {
240 pub fn parse(data: R) -> Result<Self> {
242 Ok(match FileKind::parse(data)? {
243 #[cfg(feature = "elf")]
244 FileKind::Elf32 => File::Elf32(elf::ElfFile32::parse(data)?),
245 #[cfg(feature = "elf")]
246 FileKind::Elf64 => File::Elf64(elf::ElfFile64::parse(data)?),
247 #[cfg(feature = "macho")]
248 FileKind::MachO32 => File::MachO32(macho::MachOFile32::parse(data)?),
249 #[cfg(feature = "macho")]
250 FileKind::MachO64 => File::MachO64(macho::MachOFile64::parse(data)?),
251 #[cfg(feature = "wasm")]
252 FileKind::Wasm => File::Wasm(wasm::WasmFile::parse(data)?),
253 #[cfg(feature = "pe")]
254 FileKind::Pe32 => File::Pe32(pe::PeFile32::parse(data)?),
255 #[cfg(feature = "pe")]
256 FileKind::Pe64 => File::Pe64(pe::PeFile64::parse(data)?),
257 #[cfg(feature = "coff")]
258 FileKind::Coff => File::Coff(coff::CoffFile::parse(data)?),
259 #[cfg(feature = "coff")]
260 FileKind::CoffBig => File::CoffBig(coff::CoffBigFile::parse(data)?),
261 #[cfg(feature = "xcoff")]
262 FileKind::Xcoff32 => File::Xcoff32(xcoff::XcoffFile32::parse(data)?),
263 #[cfg(feature = "xcoff")]
264 FileKind::Xcoff64 => File::Xcoff64(xcoff::XcoffFile64::parse(data)?),
265 #[allow(unreachable_patterns)]
266 _ => return Err(Error("Unsupported file format")),
267 })
268 }
269
270 #[cfg(feature = "macho")]
272 pub fn parse_dyld_cache_image<'cache, E: crate::Endian>(
273 image: &macho::DyldCacheImage<'data, 'cache, E, R>,
274 ) -> Result<Self> {
275 Ok(match image.cache.architecture().address_size() {
276 Some(read::AddressSize::U64) => {
277 File::MachO64(macho::MachOFile64::parse_dyld_cache_image(image)?)
278 }
279 Some(read::AddressSize::U32) => {
280 File::MachO32(macho::MachOFile32::parse_dyld_cache_image(image)?)
281 }
282 _ => return Err(Error("Unsupported file format")),
283 })
284 }
285
286 pub fn format(&self) -> BinaryFormat {
288 match self {
289 #[cfg(feature = "coff")]
290 File::Coff(_) | File::CoffBig(_) => BinaryFormat::Coff,
291 #[cfg(feature = "elf")]
292 File::Elf32(_) | File::Elf64(_) => BinaryFormat::Elf,
293 #[cfg(feature = "macho")]
294 File::MachO32(_) | File::MachO64(_) => BinaryFormat::MachO,
295 #[cfg(feature = "pe")]
296 File::Pe32(_) | File::Pe64(_) => BinaryFormat::Pe,
297 #[cfg(feature = "wasm")]
298 File::Wasm(_) => BinaryFormat::Wasm,
299 #[cfg(feature = "xcoff")]
300 File::Xcoff32(_) | File::Xcoff64(_) => BinaryFormat::Xcoff,
301 }
302 }
303}
304
305impl<'data, R: ReadRef<'data>> read::private::Sealed for File<'data, R> {}
306
307impl<'data, R> Object<'data> for File<'data, R>
308where
309 R: ReadRef<'data>,
310{
311 type Segment<'file>
312 = Segment<'data, 'file, R>
313 where
314 Self: 'file,
315 'data: 'file;
316 type SegmentIterator<'file>
317 = SegmentIterator<'data, 'file, R>
318 where
319 Self: 'file,
320 'data: 'file;
321 type Section<'file>
322 = Section<'data, 'file, R>
323 where
324 Self: 'file,
325 'data: 'file;
326 type SectionIterator<'file>
327 = SectionIterator<'data, 'file, R>
328 where
329 Self: 'file,
330 'data: 'file;
331 type Comdat<'file>
332 = Comdat<'data, 'file, R>
333 where
334 Self: 'file,
335 'data: 'file;
336 type ComdatIterator<'file>
337 = ComdatIterator<'data, 'file, R>
338 where
339 Self: 'file,
340 'data: 'file;
341 type Symbol<'file>
342 = Symbol<'data, 'file, R>
343 where
344 Self: 'file,
345 'data: 'file;
346 type SymbolIterator<'file>
347 = SymbolIterator<'data, 'file, R>
348 where
349 Self: 'file,
350 'data: 'file;
351 type SymbolTable<'file>
352 = SymbolTable<'data, 'file, R>
353 where
354 Self: 'file,
355 'data: 'file;
356 type DynamicRelocationIterator<'file>
357 = DynamicRelocationIterator<'data, 'file, R>
358 where
359 Self: 'file,
360 'data: 'file;
361
362 fn architecture(&self) -> Architecture {
363 with_inner!(self, File, |x| x.architecture())
364 }
365
366 fn sub_architecture(&self) -> Option<SubArchitecture> {
367 with_inner!(self, File, |x| x.sub_architecture())
368 }
369
370 fn is_little_endian(&self) -> bool {
371 with_inner!(self, File, |x| x.is_little_endian())
372 }
373
374 fn is_64(&self) -> bool {
375 with_inner!(self, File, |x| x.is_64())
376 }
377
378 fn kind(&self) -> ObjectKind {
379 with_inner!(self, File, |x| x.kind())
380 }
381
382 fn segments(&self) -> SegmentIterator<'data, '_, R> {
383 SegmentIterator {
384 inner: map_inner!(self, File, SegmentIteratorInternal, |x| x.segments()),
385 }
386 }
387
388 fn section_by_name_bytes<'file>(
389 &'file self,
390 section_name: &[u8],
391 ) -> Option<Section<'data, 'file, R>> {
392 map_inner_option!(self, File, SectionInternal, |x| x
393 .section_by_name_bytes(section_name))
394 .map(|inner| Section { inner })
395 }
396
397 fn section_by_index(&self, index: SectionIndex) -> Result<Section<'data, '_, R>> {
398 map_inner_option!(self, File, SectionInternal, |x| x.section_by_index(index))
399 .map(|inner| Section { inner })
400 }
401
402 fn sections(&self) -> SectionIterator<'data, '_, R> {
403 SectionIterator {
404 inner: map_inner!(self, File, SectionIteratorInternal, |x| x.sections()),
405 }
406 }
407
408 fn comdats(&self) -> ComdatIterator<'data, '_, R> {
409 ComdatIterator {
410 inner: map_inner!(self, File, ComdatIteratorInternal, |x| x.comdats()),
411 }
412 }
413
414 fn symbol_by_index(&self, index: SymbolIndex) -> Result<Symbol<'data, '_, R>> {
415 map_inner_option!(self, File, SymbolInternal, |x| x
416 .symbol_by_index(index)
417 .map(|x| (x, PhantomData)))
418 .map(|inner| Symbol { inner })
419 }
420
421 fn symbols(&self) -> SymbolIterator<'data, '_, R> {
422 SymbolIterator {
423 inner: map_inner!(self, File, SymbolIteratorInternal, |x| (
424 x.symbols(),
425 PhantomData
426 )),
427 }
428 }
429
430 fn symbol_table(&self) -> Option<SymbolTable<'data, '_, R>> {
431 map_inner_option!(self, File, SymbolTableInternal, |x| x
432 .symbol_table()
433 .map(|x| (x, PhantomData)))
434 .map(|inner| SymbolTable { inner })
435 }
436
437 fn dynamic_symbols(&self) -> SymbolIterator<'data, '_, R> {
438 SymbolIterator {
439 inner: map_inner!(self, File, SymbolIteratorInternal, |x| (
440 x.dynamic_symbols(),
441 PhantomData
442 )),
443 }
444 }
445
446 fn dynamic_symbol_table(&self) -> Option<SymbolTable<'data, '_, R>> {
447 map_inner_option!(self, File, SymbolTableInternal, |x| x
448 .dynamic_symbol_table()
449 .map(|x| (x, PhantomData)))
450 .map(|inner| SymbolTable { inner })
451 }
452
453 #[cfg(feature = "elf")]
454 fn dynamic_relocations(&self) -> Option<DynamicRelocationIterator<'data, '_, R>> {
455 let inner = match self {
456 File::Elf32(ref elf) => {
457 DynamicRelocationIteratorInternal::Elf32(elf.dynamic_relocations()?)
458 }
459 File::Elf64(ref elf) => {
460 DynamicRelocationIteratorInternal::Elf64(elf.dynamic_relocations()?)
461 }
462 #[allow(unreachable_patterns)]
463 _ => return None,
464 };
465 Some(DynamicRelocationIterator { inner })
466 }
467
468 #[cfg(not(feature = "elf"))]
469 fn dynamic_relocations(&self) -> Option<DynamicRelocationIterator<'data, '_, R>> {
470 None
471 }
472
473 fn symbol_map(&self) -> SymbolMap<SymbolMapName<'data>> {
474 with_inner!(self, File, |x| x.symbol_map())
475 }
476
477 fn object_map(&self) -> ObjectMap<'data> {
478 with_inner!(self, File, |x| x.object_map())
479 }
480
481 fn imports(&self) -> Result<Vec<Import<'data>>> {
482 with_inner!(self, File, |x| x.imports())
483 }
484
485 fn exports(&self) -> Result<Vec<Export<'data>>> {
486 with_inner!(self, File, |x| x.exports())
487 }
488
489 fn has_debug_symbols(&self) -> bool {
490 with_inner!(self, File, |x| x.has_debug_symbols())
491 }
492
493 #[inline]
494 fn mach_uuid(&self) -> Result<Option<[u8; 16]>> {
495 with_inner!(self, File, |x| x.mach_uuid())
496 }
497
498 #[inline]
499 fn build_id(&self) -> Result<Option<&'data [u8]>> {
500 with_inner!(self, File, |x| x.build_id())
501 }
502
503 #[inline]
504 fn gnu_debuglink(&self) -> Result<Option<(&'data [u8], u32)>> {
505 with_inner!(self, File, |x| x.gnu_debuglink())
506 }
507
508 #[inline]
509 fn gnu_debugaltlink(&self) -> Result<Option<(&'data [u8], &'data [u8])>> {
510 with_inner!(self, File, |x| x.gnu_debugaltlink())
511 }
512
513 #[inline]
514 fn pdb_info(&self) -> Result<Option<CodeView<'_>>> {
515 with_inner!(self, File, |x| x.pdb_info())
516 }
517
518 fn relative_address_base(&self) -> u64 {
519 with_inner!(self, File, |x| x.relative_address_base())
520 }
521
522 fn entry(&self) -> u64 {
523 with_inner!(self, File, |x| x.entry())
524 }
525
526 fn flags(&self) -> FileFlags {
527 with_inner!(self, File, |x| x.flags())
528 }
529}
530
531#[derive(Debug)]
533pub struct SegmentIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> {
534 inner: SegmentIteratorInternal<'data, 'file, R>,
535}
536
537#[derive(Debug)]
538enum SegmentIteratorInternal<'data, 'file, R: ReadRef<'data>> {
539 #[cfg(feature = "coff")]
540 Coff(coff::CoffSegmentIterator<'data, 'file, R>),
541 #[cfg(feature = "coff")]
542 CoffBig(coff::CoffBigSegmentIterator<'data, 'file, R>),
543 #[cfg(feature = "elf")]
544 Elf32(elf::ElfSegmentIterator32<'data, 'file, Endianness, R>),
545 #[cfg(feature = "elf")]
546 Elf64(elf::ElfSegmentIterator64<'data, 'file, Endianness, R>),
547 #[cfg(feature = "macho")]
548 MachO32(macho::MachOSegmentIterator32<'data, 'file, Endianness, R>),
549 #[cfg(feature = "macho")]
550 MachO64(macho::MachOSegmentIterator64<'data, 'file, Endianness, R>),
551 #[cfg(feature = "pe")]
552 Pe32(pe::PeSegmentIterator32<'data, 'file, R>),
553 #[cfg(feature = "pe")]
554 Pe64(pe::PeSegmentIterator64<'data, 'file, R>),
555 #[cfg(feature = "wasm")]
556 Wasm(wasm::WasmSegmentIterator<'data, 'file, R>),
557 #[cfg(feature = "xcoff")]
558 Xcoff32(xcoff::XcoffSegmentIterator32<'data, 'file, R>),
559 #[cfg(feature = "xcoff")]
560 Xcoff64(xcoff::XcoffSegmentIterator64<'data, 'file, R>),
561}
562
563impl<'data, 'file, R: ReadRef<'data>> Iterator for SegmentIterator<'data, 'file, R> {
564 type Item = Segment<'data, 'file, R>;
565
566 fn next(&mut self) -> Option<Self::Item> {
567 next_inner!(self.inner, SegmentIteratorInternal, SegmentInternal)
568 .map(|inner| Segment { inner })
569 }
570}
571
572pub struct Segment<'data, 'file, R: ReadRef<'data> = &'data [u8]> {
576 inner: SegmentInternal<'data, 'file, R>,
577}
578
579#[derive(Debug)]
580enum SegmentInternal<'data, 'file, R: ReadRef<'data>> {
581 #[cfg(feature = "coff")]
582 Coff(coff::CoffSegment<'data, 'file, R>),
583 #[cfg(feature = "coff")]
584 CoffBig(coff::CoffBigSegment<'data, 'file, R>),
585 #[cfg(feature = "elf")]
586 Elf32(elf::ElfSegment32<'data, 'file, Endianness, R>),
587 #[cfg(feature = "elf")]
588 Elf64(elf::ElfSegment64<'data, 'file, Endianness, R>),
589 #[cfg(feature = "macho")]
590 MachO32(macho::MachOSegment32<'data, 'file, Endianness, R>),
591 #[cfg(feature = "macho")]
592 MachO64(macho::MachOSegment64<'data, 'file, Endianness, R>),
593 #[cfg(feature = "pe")]
594 Pe32(pe::PeSegment32<'data, 'file, R>),
595 #[cfg(feature = "pe")]
596 Pe64(pe::PeSegment64<'data, 'file, R>),
597 #[cfg(feature = "wasm")]
598 Wasm(wasm::WasmSegment<'data, 'file, R>),
599 #[cfg(feature = "xcoff")]
600 Xcoff32(xcoff::XcoffSegment32<'data, 'file, R>),
601 #[cfg(feature = "xcoff")]
602 Xcoff64(xcoff::XcoffSegment64<'data, 'file, R>),
603}
604
605impl<'data, 'file, R: ReadRef<'data>> fmt::Debug for Segment<'data, 'file, R> {
606 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
607 let mut s = f.debug_struct("Segment");
609 match self.name() {
610 Ok(Some(ref name)) => {
611 s.field("name", name);
612 }
613 Ok(None) => {}
614 Err(_) => {
615 s.field("name", &"<invalid>");
616 }
617 }
618 s.field("address", &self.address())
619 .field("size", &self.size())
620 .field("permissions", &self.permissions())
621 .finish()
622 }
623}
624
625impl<'data, 'file, R: ReadRef<'data>> read::private::Sealed for Segment<'data, 'file, R> {}
626
627impl<'data, 'file, R: ReadRef<'data>> ObjectSegment<'data> for Segment<'data, 'file, R> {
628 fn address(&self) -> u64 {
629 with_inner!(self.inner, SegmentInternal, |x| x.address())
630 }
631
632 fn size(&self) -> u64 {
633 with_inner!(self.inner, SegmentInternal, |x| x.size())
634 }
635
636 fn align(&self) -> u64 {
637 with_inner!(self.inner, SegmentInternal, |x| x.align())
638 }
639
640 fn file_range(&self) -> (u64, u64) {
641 with_inner!(self.inner, SegmentInternal, |x| x.file_range())
642 }
643
644 fn data(&self) -> Result<&'data [u8]> {
645 with_inner!(self.inner, SegmentInternal, |x| x.data())
646 }
647
648 fn data_range(&self, address: u64, size: u64) -> Result<Option<&'data [u8]>> {
649 with_inner!(self.inner, SegmentInternal, |x| x.data_range(address, size))
650 }
651
652 fn name_bytes(&self) -> Result<Option<&[u8]>> {
653 with_inner!(self.inner, SegmentInternal, |x| x.name_bytes())
654 }
655
656 fn name(&self) -> Result<Option<&str>> {
657 with_inner!(self.inner, SegmentInternal, |x| x.name())
658 }
659
660 fn flags(&self) -> SegmentFlags {
661 with_inner!(self.inner, SegmentInternal, |x| x.flags())
662 }
663
664 fn permissions(&self) -> Permissions {
665 with_inner!(self.inner, SegmentInternal, |x| x.permissions())
666 }
667}
668
669#[derive(Debug)]
671pub struct SectionIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> {
672 inner: SectionIteratorInternal<'data, 'file, R>,
673}
674
675#[derive(Debug)]
677enum SectionIteratorInternal<'data, 'file, R: ReadRef<'data>> {
678 #[cfg(feature = "coff")]
679 Coff(coff::CoffSectionIterator<'data, 'file, R>),
680 #[cfg(feature = "coff")]
681 CoffBig(coff::CoffBigSectionIterator<'data, 'file, R>),
682 #[cfg(feature = "elf")]
683 Elf32(elf::ElfSectionIterator32<'data, 'file, Endianness, R>),
684 #[cfg(feature = "elf")]
685 Elf64(elf::ElfSectionIterator64<'data, 'file, Endianness, R>),
686 #[cfg(feature = "macho")]
687 MachO32(macho::MachOSectionIterator32<'data, 'file, Endianness, R>),
688 #[cfg(feature = "macho")]
689 MachO64(macho::MachOSectionIterator64<'data, 'file, Endianness, R>),
690 #[cfg(feature = "pe")]
691 Pe32(pe::PeSectionIterator32<'data, 'file, R>),
692 #[cfg(feature = "pe")]
693 Pe64(pe::PeSectionIterator64<'data, 'file, R>),
694 #[cfg(feature = "wasm")]
695 Wasm(wasm::WasmSectionIterator<'data, 'file, R>),
696 #[cfg(feature = "xcoff")]
697 Xcoff32(xcoff::XcoffSectionIterator32<'data, 'file, R>),
698 #[cfg(feature = "xcoff")]
699 Xcoff64(xcoff::XcoffSectionIterator64<'data, 'file, R>),
700}
701
702impl<'data, 'file, R: ReadRef<'data>> Iterator for SectionIterator<'data, 'file, R> {
703 type Item = Section<'data, 'file, R>;
704
705 fn next(&mut self) -> Option<Self::Item> {
706 next_inner!(self.inner, SectionIteratorInternal, SectionInternal)
707 .map(|inner| Section { inner })
708 }
709}
710
711pub struct Section<'data, 'file, R: ReadRef<'data> = &'data [u8]> {
715 inner: SectionInternal<'data, 'file, R>,
716}
717
718enum SectionInternal<'data, 'file, R: ReadRef<'data>> {
719 #[cfg(feature = "coff")]
720 Coff(coff::CoffSection<'data, 'file, R>),
721 #[cfg(feature = "coff")]
722 CoffBig(coff::CoffBigSection<'data, 'file, R>),
723 #[cfg(feature = "elf")]
724 Elf32(elf::ElfSection32<'data, 'file, Endianness, R>),
725 #[cfg(feature = "elf")]
726 Elf64(elf::ElfSection64<'data, 'file, Endianness, R>),
727 #[cfg(feature = "macho")]
728 MachO32(macho::MachOSection32<'data, 'file, Endianness, R>),
729 #[cfg(feature = "macho")]
730 MachO64(macho::MachOSection64<'data, 'file, Endianness, R>),
731 #[cfg(feature = "pe")]
732 Pe32(pe::PeSection32<'data, 'file, R>),
733 #[cfg(feature = "pe")]
734 Pe64(pe::PeSection64<'data, 'file, R>),
735 #[cfg(feature = "wasm")]
736 Wasm(wasm::WasmSection<'data, 'file, R>),
737 #[cfg(feature = "xcoff")]
738 Xcoff32(xcoff::XcoffSection32<'data, 'file, R>),
739 #[cfg(feature = "xcoff")]
740 Xcoff64(xcoff::XcoffSection64<'data, 'file, R>),
741}
742
743impl<'data, 'file, R: ReadRef<'data>> fmt::Debug for Section<'data, 'file, R> {
744 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
745 let mut s = f.debug_struct("Section");
747 match self.segment_name() {
748 Ok(Some(ref name)) => {
749 s.field("segment", name);
750 }
751 Ok(None) => {}
752 Err(_) => {
753 s.field("segment", &"<invalid>");
754 }
755 }
756 s.field("name", &self.name().unwrap_or("<invalid>"))
757 .field("address", &self.address())
758 .field("size", &self.size())
759 .field("align", &self.align())
760 .field("kind", &self.kind())
761 .field("flags", &self.flags())
762 .finish()
763 }
764}
765
766impl<'data, 'file, R: ReadRef<'data>> read::private::Sealed for Section<'data, 'file, R> {}
767
768impl<'data, 'file, R: ReadRef<'data>> ObjectSection<'data> for Section<'data, 'file, R> {
769 type RelocationIterator = SectionRelocationIterator<'data, 'file, R>;
770
771 fn index(&self) -> SectionIndex {
772 with_inner!(self.inner, SectionInternal, |x| x.index())
773 }
774
775 fn address(&self) -> u64 {
776 with_inner!(self.inner, SectionInternal, |x| x.address())
777 }
778
779 fn size(&self) -> u64 {
780 with_inner!(self.inner, SectionInternal, |x| x.size())
781 }
782
783 fn align(&self) -> u64 {
784 with_inner!(self.inner, SectionInternal, |x| x.align())
785 }
786
787 fn file_range(&self) -> Option<(u64, u64)> {
788 with_inner!(self.inner, SectionInternal, |x| x.file_range())
789 }
790
791 fn data(&self) -> Result<&'data [u8]> {
792 with_inner!(self.inner, SectionInternal, |x| x.data())
793 }
794
795 fn data_range(&self, address: u64, size: u64) -> Result<Option<&'data [u8]>> {
796 with_inner!(self.inner, SectionInternal, |x| x.data_range(address, size))
797 }
798
799 fn compressed_file_range(&self) -> Result<CompressedFileRange> {
800 with_inner!(self.inner, SectionInternal, |x| x.compressed_file_range())
801 }
802
803 fn compressed_data(&self) -> Result<CompressedData<'data>> {
804 with_inner!(self.inner, SectionInternal, |x| x.compressed_data())
805 }
806
807 fn name_bytes(&self) -> Result<&'data [u8]> {
808 with_inner!(self.inner, SectionInternal, |x| x.name_bytes())
809 }
810
811 fn name(&self) -> Result<&'data str> {
812 with_inner!(self.inner, SectionInternal, |x| x.name())
813 }
814
815 fn segment_name_bytes(&self) -> Result<Option<&[u8]>> {
816 with_inner!(self.inner, SectionInternal, |x| x.segment_name_bytes())
817 }
818
819 fn segment_name(&self) -> Result<Option<&str>> {
820 with_inner!(self.inner, SectionInternal, |x| x.segment_name())
821 }
822
823 fn kind(&self) -> SectionKind {
824 with_inner!(self.inner, SectionInternal, |x| x.kind())
825 }
826
827 fn relocations(&self) -> SectionRelocationIterator<'data, 'file, R> {
828 SectionRelocationIterator {
829 inner: map_inner!(
830 self.inner,
831 SectionInternal,
832 SectionRelocationIteratorInternal,
833 |x| x.relocations()
834 ),
835 }
836 }
837
838 fn relocation_map(&self) -> Result<RelocationMap> {
839 with_inner!(self.inner, SectionInternal, |x| x.relocation_map())
840 }
841
842 fn flags(&self) -> SectionFlags {
843 with_inner!(self.inner, SectionInternal, |x| x.flags())
844 }
845}
846
847#[derive(Debug)]
849pub struct ComdatIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> {
850 inner: ComdatIteratorInternal<'data, 'file, R>,
851}
852
853#[derive(Debug)]
854enum ComdatIteratorInternal<'data, 'file, R: ReadRef<'data>> {
855 #[cfg(feature = "coff")]
856 Coff(coff::CoffComdatIterator<'data, 'file, R>),
857 #[cfg(feature = "coff")]
858 CoffBig(coff::CoffBigComdatIterator<'data, 'file, R>),
859 #[cfg(feature = "elf")]
860 Elf32(elf::ElfComdatIterator32<'data, 'file, Endianness, R>),
861 #[cfg(feature = "elf")]
862 Elf64(elf::ElfComdatIterator64<'data, 'file, Endianness, R>),
863 #[cfg(feature = "macho")]
864 MachO32(macho::MachOComdatIterator32<'data, 'file, Endianness, R>),
865 #[cfg(feature = "macho")]
866 MachO64(macho::MachOComdatIterator64<'data, 'file, Endianness, R>),
867 #[cfg(feature = "pe")]
868 Pe32(pe::PeComdatIterator32<'data, 'file, R>),
869 #[cfg(feature = "pe")]
870 Pe64(pe::PeComdatIterator64<'data, 'file, R>),
871 #[cfg(feature = "wasm")]
872 Wasm(wasm::WasmComdatIterator<'data, 'file, R>),
873 #[cfg(feature = "xcoff")]
874 Xcoff32(xcoff::XcoffComdatIterator32<'data, 'file, R>),
875 #[cfg(feature = "xcoff")]
876 Xcoff64(xcoff::XcoffComdatIterator64<'data, 'file, R>),
877}
878
879impl<'data, 'file, R: ReadRef<'data>> Iterator for ComdatIterator<'data, 'file, R> {
880 type Item = Comdat<'data, 'file, R>;
881
882 fn next(&mut self) -> Option<Self::Item> {
883 next_inner!(self.inner, ComdatIteratorInternal, ComdatInternal)
884 .map(|inner| Comdat { inner })
885 }
886}
887
888pub struct Comdat<'data, 'file, R: ReadRef<'data> = &'data [u8]> {
892 inner: ComdatInternal<'data, 'file, R>,
893}
894
895enum ComdatInternal<'data, 'file, R: ReadRef<'data>> {
896 #[cfg(feature = "coff")]
897 Coff(coff::CoffComdat<'data, 'file, R>),
898 #[cfg(feature = "coff")]
899 CoffBig(coff::CoffBigComdat<'data, 'file, R>),
900 #[cfg(feature = "elf")]
901 Elf32(elf::ElfComdat32<'data, 'file, Endianness, R>),
902 #[cfg(feature = "elf")]
903 Elf64(elf::ElfComdat64<'data, 'file, Endianness, R>),
904 #[cfg(feature = "macho")]
905 MachO32(macho::MachOComdat32<'data, 'file, Endianness, R>),
906 #[cfg(feature = "macho")]
907 MachO64(macho::MachOComdat64<'data, 'file, Endianness, R>),
908 #[cfg(feature = "pe")]
909 Pe32(pe::PeComdat32<'data, 'file, R>),
910 #[cfg(feature = "pe")]
911 Pe64(pe::PeComdat64<'data, 'file, R>),
912 #[cfg(feature = "wasm")]
913 Wasm(wasm::WasmComdat<'data, 'file, R>),
914 #[cfg(feature = "xcoff")]
915 Xcoff32(xcoff::XcoffComdat32<'data, 'file, R>),
916 #[cfg(feature = "xcoff")]
917 Xcoff64(xcoff::XcoffComdat64<'data, 'file, R>),
918}
919
920impl<'data, 'file, R: ReadRef<'data>> fmt::Debug for Comdat<'data, 'file, R> {
921 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
922 let mut s = f.debug_struct("Comdat");
923 s.field("symbol", &self.symbol())
924 .field("name", &self.name().unwrap_or("<invalid>"))
925 .field("kind", &self.kind())
926 .finish()
927 }
928}
929
930impl<'data, 'file, R: ReadRef<'data>> read::private::Sealed for Comdat<'data, 'file, R> {}
931
932impl<'data, 'file, R: ReadRef<'data>> ObjectComdat<'data> for Comdat<'data, 'file, R> {
933 type SectionIterator = ComdatSectionIterator<'data, 'file, R>;
934
935 fn kind(&self) -> ComdatKind {
936 with_inner!(self.inner, ComdatInternal, |x| x.kind())
937 }
938
939 fn symbol(&self) -> SymbolIndex {
940 with_inner!(self.inner, ComdatInternal, |x| x.symbol())
941 }
942
943 fn name_bytes(&self) -> Result<&'data [u8]> {
944 with_inner!(self.inner, ComdatInternal, |x| x.name_bytes())
945 }
946
947 fn name(&self) -> Result<&'data str> {
948 with_inner!(self.inner, ComdatInternal, |x| x.name())
949 }
950
951 fn sections(&self) -> ComdatSectionIterator<'data, 'file, R> {
952 ComdatSectionIterator {
953 inner: map_inner!(
954 self.inner,
955 ComdatInternal,
956 ComdatSectionIteratorInternal,
957 |x| x.sections()
958 ),
959 }
960 }
961}
962
963#[derive(Debug)]
965pub struct ComdatSectionIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> {
966 inner: ComdatSectionIteratorInternal<'data, 'file, R>,
967}
968
969#[derive(Debug)]
970enum ComdatSectionIteratorInternal<'data, 'file, R: ReadRef<'data>> {
971 #[cfg(feature = "coff")]
972 Coff(coff::CoffComdatSectionIterator<'data, 'file, R>),
973 #[cfg(feature = "coff")]
974 CoffBig(coff::CoffBigComdatSectionIterator<'data, 'file, R>),
975 #[cfg(feature = "elf")]
976 Elf32(elf::ElfComdatSectionIterator32<'data, 'file, Endianness, R>),
977 #[cfg(feature = "elf")]
978 Elf64(elf::ElfComdatSectionIterator64<'data, 'file, Endianness, R>),
979 #[cfg(feature = "macho")]
980 MachO32(macho::MachOComdatSectionIterator32<'data, 'file, Endianness, R>),
981 #[cfg(feature = "macho")]
982 MachO64(macho::MachOComdatSectionIterator64<'data, 'file, Endianness, R>),
983 #[cfg(feature = "pe")]
984 Pe32(pe::PeComdatSectionIterator32<'data, 'file, R>),
985 #[cfg(feature = "pe")]
986 Pe64(pe::PeComdatSectionIterator64<'data, 'file, R>),
987 #[cfg(feature = "wasm")]
988 Wasm(wasm::WasmComdatSectionIterator<'data, 'file, R>),
989 #[cfg(feature = "xcoff")]
990 Xcoff32(xcoff::XcoffComdatSectionIterator32<'data, 'file, R>),
991 #[cfg(feature = "xcoff")]
992 Xcoff64(xcoff::XcoffComdatSectionIterator64<'data, 'file, R>),
993}
994
995impl<'data, 'file, R: ReadRef<'data>> Iterator for ComdatSectionIterator<'data, 'file, R> {
996 type Item = SectionIndex;
997
998 fn next(&mut self) -> Option<Self::Item> {
999 with_inner_mut!(self.inner, ComdatSectionIteratorInternal, |x| x.next())
1000 }
1001}
1002
1003#[derive(Debug)]
1007pub struct SymbolTable<'data, 'file, R = &'data [u8]>
1008where
1009 R: ReadRef<'data>,
1010{
1011 inner: SymbolTableInternal<'data, 'file, R>,
1012}
1013
1014#[derive(Debug)]
1015enum SymbolTableInternal<'data, 'file, R>
1016where
1017 R: ReadRef<'data>,
1018{
1019 #[cfg(feature = "coff")]
1020 Coff((coff::CoffSymbolTable<'data, 'file, R>, PhantomData<R>)),
1021 #[cfg(feature = "coff")]
1022 CoffBig((coff::CoffBigSymbolTable<'data, 'file, R>, PhantomData<R>)),
1023 #[cfg(feature = "elf")]
1024 Elf32(
1025 (
1026 elf::ElfSymbolTable32<'data, 'file, Endianness, R>,
1027 PhantomData<R>,
1028 ),
1029 ),
1030 #[cfg(feature = "elf")]
1031 Elf64(
1032 (
1033 elf::ElfSymbolTable64<'data, 'file, Endianness, R>,
1034 PhantomData<R>,
1035 ),
1036 ),
1037 #[cfg(feature = "macho")]
1038 MachO32(
1039 (
1040 macho::MachOSymbolTable32<'data, 'file, Endianness, R>,
1041 PhantomData<()>,
1042 ),
1043 ),
1044 #[cfg(feature = "macho")]
1045 MachO64(
1046 (
1047 macho::MachOSymbolTable64<'data, 'file, Endianness, R>,
1048 PhantomData<()>,
1049 ),
1050 ),
1051 #[cfg(feature = "pe")]
1052 Pe32((coff::CoffSymbolTable<'data, 'file, R>, PhantomData<R>)),
1053 #[cfg(feature = "pe")]
1054 Pe64((coff::CoffSymbolTable<'data, 'file, R>, PhantomData<R>)),
1055 #[cfg(feature = "wasm")]
1056 Wasm((wasm::WasmSymbolTable<'data, 'file>, PhantomData<R>)),
1057 #[cfg(feature = "xcoff")]
1058 Xcoff32((xcoff::XcoffSymbolTable32<'data, 'file, R>, PhantomData<R>)),
1059 #[cfg(feature = "xcoff")]
1060 Xcoff64((xcoff::XcoffSymbolTable64<'data, 'file, R>, PhantomData<R>)),
1061}
1062
1063impl<'data, 'file, R: ReadRef<'data>> read::private::Sealed for SymbolTable<'data, 'file, R> {}
1064
1065impl<'data, 'file, R: ReadRef<'data>> ObjectSymbolTable<'data> for SymbolTable<'data, 'file, R> {
1066 type Symbol = Symbol<'data, 'file, R>;
1067 type SymbolIterator = SymbolIterator<'data, 'file, R>;
1068
1069 fn symbols(&self) -> Self::SymbolIterator {
1070 SymbolIterator {
1071 inner: map_inner!(
1072 self.inner,
1073 SymbolTableInternal,
1074 SymbolIteratorInternal,
1075 |x| (x.0.symbols(), PhantomData)
1076 ),
1077 }
1078 }
1079
1080 fn symbol_by_index(&self, index: SymbolIndex) -> Result<Self::Symbol> {
1081 map_inner_option!(self.inner, SymbolTableInternal, SymbolInternal, |x| x
1082 .0
1083 .symbol_by_index(index)
1084 .map(|x| (x, PhantomData)))
1085 .map(|inner| Symbol { inner })
1086 }
1087}
1088
1089#[derive(Debug)]
1091pub struct SymbolIterator<'data, 'file, R = &'data [u8]>
1092where
1093 R: ReadRef<'data>,
1094{
1095 inner: SymbolIteratorInternal<'data, 'file, R>,
1096}
1097
1098#[derive(Debug)]
1099enum SymbolIteratorInternal<'data, 'file, R>
1100where
1101 R: ReadRef<'data>,
1102{
1103 #[cfg(feature = "coff")]
1104 Coff((coff::CoffSymbolIterator<'data, 'file, R>, PhantomData<R>)),
1105 #[cfg(feature = "coff")]
1106 CoffBig((coff::CoffBigSymbolIterator<'data, 'file, R>, PhantomData<R>)),
1107 #[cfg(feature = "elf")]
1108 Elf32(
1109 (
1110 elf::ElfSymbolIterator32<'data, 'file, Endianness, R>,
1111 PhantomData<R>,
1112 ),
1113 ),
1114 #[cfg(feature = "elf")]
1115 Elf64(
1116 (
1117 elf::ElfSymbolIterator64<'data, 'file, Endianness, R>,
1118 PhantomData<R>,
1119 ),
1120 ),
1121 #[cfg(feature = "macho")]
1122 MachO32(
1123 (
1124 macho::MachOSymbolIterator32<'data, 'file, Endianness, R>,
1125 PhantomData<()>,
1126 ),
1127 ),
1128 #[cfg(feature = "macho")]
1129 MachO64(
1130 (
1131 macho::MachOSymbolIterator64<'data, 'file, Endianness, R>,
1132 PhantomData<()>,
1133 ),
1134 ),
1135 #[cfg(feature = "pe")]
1136 Pe32((coff::CoffSymbolIterator<'data, 'file, R>, PhantomData<R>)),
1137 #[cfg(feature = "pe")]
1138 Pe64((coff::CoffSymbolIterator<'data, 'file, R>, PhantomData<R>)),
1139 #[cfg(feature = "wasm")]
1140 Wasm((wasm::WasmSymbolIterator<'data, 'file>, PhantomData<R>)),
1141 #[cfg(feature = "xcoff")]
1142 Xcoff32(
1143 (
1144 xcoff::XcoffSymbolIterator32<'data, 'file, R>,
1145 PhantomData<R>,
1146 ),
1147 ),
1148 #[cfg(feature = "xcoff")]
1149 Xcoff64(
1150 (
1151 xcoff::XcoffSymbolIterator64<'data, 'file, R>,
1152 PhantomData<R>,
1153 ),
1154 ),
1155}
1156
1157impl<'data, 'file, R: ReadRef<'data>> Iterator for SymbolIterator<'data, 'file, R> {
1158 type Item = Symbol<'data, 'file, R>;
1159
1160 fn next(&mut self) -> Option<Self::Item> {
1161 map_inner_option_mut!(self.inner, SymbolIteratorInternal, SymbolInternal, |iter| {
1162 iter.0.next().map(|x| (x, PhantomData))
1163 })
1164 .map(|inner| Symbol { inner })
1165 }
1166}
1167
1168pub struct Symbol<'data, 'file, R = &'data [u8]>
1172where
1173 R: ReadRef<'data>,
1174{
1175 inner: SymbolInternal<'data, 'file, R>,
1176}
1177
1178enum SymbolInternal<'data, 'file, R>
1179where
1180 R: ReadRef<'data>,
1181{
1182 #[cfg(feature = "coff")]
1183 Coff((coff::CoffSymbol<'data, 'file, R>, PhantomData<R>)),
1184 #[cfg(feature = "coff")]
1185 CoffBig((coff::CoffBigSymbol<'data, 'file, R>, PhantomData<R>)),
1186 #[cfg(feature = "elf")]
1187 Elf32(
1188 (
1189 elf::ElfSymbol32<'data, 'file, Endianness, R>,
1190 PhantomData<R>,
1191 ),
1192 ),
1193 #[cfg(feature = "elf")]
1194 Elf64(
1195 (
1196 elf::ElfSymbol64<'data, 'file, Endianness, R>,
1197 PhantomData<R>,
1198 ),
1199 ),
1200 #[cfg(feature = "macho")]
1201 MachO32(
1202 (
1203 macho::MachOSymbol32<'data, 'file, Endianness, R>,
1204 PhantomData<()>,
1205 ),
1206 ),
1207 #[cfg(feature = "macho")]
1208 MachO64(
1209 (
1210 macho::MachOSymbol64<'data, 'file, Endianness, R>,
1211 PhantomData<()>,
1212 ),
1213 ),
1214 #[cfg(feature = "pe")]
1215 Pe32((coff::CoffSymbol<'data, 'file, R>, PhantomData<R>)),
1216 #[cfg(feature = "pe")]
1217 Pe64((coff::CoffSymbol<'data, 'file, R>, PhantomData<R>)),
1218 #[cfg(feature = "wasm")]
1219 Wasm((wasm::WasmSymbol<'data, 'file>, PhantomData<R>)),
1220 #[cfg(feature = "xcoff")]
1221 Xcoff32((xcoff::XcoffSymbol32<'data, 'file, R>, PhantomData<R>)),
1222 #[cfg(feature = "xcoff")]
1223 Xcoff64((xcoff::XcoffSymbol64<'data, 'file, R>, PhantomData<R>)),
1224}
1225
1226impl<'data, 'file, R: ReadRef<'data>> fmt::Debug for Symbol<'data, 'file, R> {
1227 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1228 f.debug_struct("Symbol")
1229 .field("name", &self.name().unwrap_or("<invalid>"))
1230 .field("address", &self.address())
1231 .field("size", &self.size())
1232 .field("kind", &self.kind())
1233 .field("section", &self.section())
1234 .field("scope", &self.scope())
1235 .field("weak", &self.is_weak())
1236 .field("flags", &self.flags())
1237 .finish()
1238 }
1239}
1240
1241impl<'data, 'file, R: ReadRef<'data>> read::private::Sealed for Symbol<'data, 'file, R> {}
1242
1243impl<'data, 'file, R: ReadRef<'data>> ObjectSymbol<'data> for Symbol<'data, 'file, R> {
1244 fn index(&self) -> SymbolIndex {
1245 with_inner!(self.inner, SymbolInternal, |x| x.0.index())
1246 }
1247
1248 fn name_bytes(&self) -> Result<&'data [u8]> {
1249 with_inner!(self.inner, SymbolInternal, |x| x.0.name_bytes())
1250 }
1251
1252 fn name(&self) -> Result<&'data str> {
1253 with_inner!(self.inner, SymbolInternal, |x| x.0.name())
1254 }
1255
1256 fn address(&self) -> u64 {
1257 with_inner!(self.inner, SymbolInternal, |x| x.0.address())
1258 }
1259
1260 fn size(&self) -> u64 {
1261 with_inner!(self.inner, SymbolInternal, |x| x.0.size())
1262 }
1263
1264 fn kind(&self) -> SymbolKind {
1265 with_inner!(self.inner, SymbolInternal, |x| x.0.kind())
1266 }
1267
1268 fn section(&self) -> SymbolSection {
1269 with_inner!(self.inner, SymbolInternal, |x| x.0.section())
1270 }
1271
1272 fn is_undefined(&self) -> bool {
1273 with_inner!(self.inner, SymbolInternal, |x| x.0.is_undefined())
1274 }
1275
1276 fn is_definition(&self) -> bool {
1277 with_inner!(self.inner, SymbolInternal, |x| x.0.is_definition())
1278 }
1279
1280 fn is_common(&self) -> bool {
1281 with_inner!(self.inner, SymbolInternal, |x| x.0.is_common())
1282 }
1283
1284 fn is_weak(&self) -> bool {
1285 with_inner!(self.inner, SymbolInternal, |x| x.0.is_weak())
1286 }
1287
1288 fn scope(&self) -> SymbolScope {
1289 with_inner!(self.inner, SymbolInternal, |x| x.0.scope())
1290 }
1291
1292 fn is_global(&self) -> bool {
1293 with_inner!(self.inner, SymbolInternal, |x| x.0.is_global())
1294 }
1295
1296 fn is_local(&self) -> bool {
1297 with_inner!(self.inner, SymbolInternal, |x| x.0.is_local())
1298 }
1299
1300 fn flags(&self) -> SymbolFlags<SectionIndex, SymbolIndex> {
1301 with_inner!(self.inner, SymbolInternal, |x| x.0.flags())
1302 }
1303}
1304
1305#[derive(Debug)]
1307pub struct DynamicRelocationIterator<'data, 'file, R = &'data [u8]>
1308where
1309 R: ReadRef<'data>,
1310{
1311 inner: DynamicRelocationIteratorInternal<'data, 'file, R>,
1312}
1313
1314#[derive(Debug)]
1315enum DynamicRelocationIteratorInternal<'data, 'file, R>
1316where
1317 R: ReadRef<'data>,
1318{
1319 #[cfg(feature = "elf")]
1320 Elf32(elf::ElfDynamicRelocationIterator32<'data, 'file, Endianness, R>),
1321 #[cfg(feature = "elf")]
1322 Elf64(elf::ElfDynamicRelocationIterator64<'data, 'file, Endianness, R>),
1323 #[allow(unused)]
1325 None(PhantomData<(&'data (), &'file (), R)>),
1326}
1327
1328impl<'data, 'file, R: ReadRef<'data>> Iterator for DynamicRelocationIterator<'data, 'file, R> {
1329 type Item = (u64, Relocation);
1330
1331 fn next(&mut self) -> Option<Self::Item> {
1332 match self.inner {
1333 #[cfg(feature = "elf")]
1334 DynamicRelocationIteratorInternal::Elf32(ref mut elf) => elf.next(),
1335 #[cfg(feature = "elf")]
1336 DynamicRelocationIteratorInternal::Elf64(ref mut elf) => elf.next(),
1337 DynamicRelocationIteratorInternal::None(_) => None,
1338 }
1339 }
1340}
1341
1342#[derive(Debug)]
1344pub struct SectionRelocationIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> {
1345 inner: SectionRelocationIteratorInternal<'data, 'file, R>,
1346}
1347
1348#[derive(Debug)]
1349enum SectionRelocationIteratorInternal<'data, 'file, R: ReadRef<'data>> {
1350 #[cfg(feature = "coff")]
1351 Coff(coff::CoffRelocationIterator<'data, 'file, R>),
1352 #[cfg(feature = "coff")]
1353 CoffBig(coff::CoffBigRelocationIterator<'data, 'file, R>),
1354 #[cfg(feature = "elf")]
1355 Elf32(elf::ElfSectionRelocationIterator32<'data, 'file, Endianness, R>),
1356 #[cfg(feature = "elf")]
1357 Elf64(elf::ElfSectionRelocationIterator64<'data, 'file, Endianness, R>),
1358 #[cfg(feature = "macho")]
1359 MachO32(macho::MachORelocationIterator32<'data, 'file, Endianness, R>),
1360 #[cfg(feature = "macho")]
1361 MachO64(macho::MachORelocationIterator64<'data, 'file, Endianness, R>),
1362 #[cfg(feature = "pe")]
1363 Pe32(pe::PeRelocationIterator<'data, 'file, R>),
1364 #[cfg(feature = "pe")]
1365 Pe64(pe::PeRelocationIterator<'data, 'file, R>),
1366 #[cfg(feature = "wasm")]
1367 Wasm(wasm::WasmRelocationIterator<'data, 'file, R>),
1368 #[cfg(feature = "xcoff")]
1369 Xcoff32(xcoff::XcoffRelocationIterator32<'data, 'file, R>),
1370 #[cfg(feature = "xcoff")]
1371 Xcoff64(xcoff::XcoffRelocationIterator64<'data, 'file, R>),
1372}
1373
1374impl<'data, 'file, R: ReadRef<'data>> Iterator for SectionRelocationIterator<'data, 'file, R> {
1375 type Item = (u64, Relocation);
1376
1377 fn next(&mut self) -> Option<Self::Item> {
1378 with_inner_mut!(self.inner, SectionRelocationIteratorInternal, |x| x.next())
1379 }
1380}