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