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> = Segment<'data, 'file, R> where Self: 'file, 'data: 'file;
311 type SegmentIterator<'file> = SegmentIterator<'data, 'file, R> where Self: 'file, 'data: 'file;
312 type Section<'file> = Section<'data, 'file, R> where Self: 'file, 'data: 'file;
313 type SectionIterator<'file> = SectionIterator<'data, 'file, R> where Self: 'file, 'data: 'file;
314 type Comdat<'file> = Comdat<'data, 'file, R> where Self: 'file, 'data: 'file;
315 type ComdatIterator<'file> = ComdatIterator<'data, 'file, R> where Self: 'file, 'data: 'file;
316 type Symbol<'file> = Symbol<'data, 'file, R> where Self: 'file, 'data: 'file;
317 type SymbolIterator<'file> = SymbolIterator<'data, 'file, R> where Self: 'file, 'data: 'file;
318 type SymbolTable<'file> = SymbolTable<'data, 'file, R> where Self: 'file, 'data: 'file;
319 type DynamicRelocationIterator<'file> = DynamicRelocationIterator<'data, 'file, R> where Self: 'file, 'data: 'file;
320
321 fn architecture(&self) -> Architecture {
322 with_inner!(self, File, |x| x.architecture())
323 }
324
325 fn sub_architecture(&self) -> Option<SubArchitecture> {
326 with_inner!(self, File, |x| x.sub_architecture())
327 }
328
329 fn is_little_endian(&self) -> bool {
330 with_inner!(self, File, |x| x.is_little_endian())
331 }
332
333 fn is_64(&self) -> bool {
334 with_inner!(self, File, |x| x.is_64())
335 }
336
337 fn kind(&self) -> ObjectKind {
338 with_inner!(self, File, |x| x.kind())
339 }
340
341 fn segments(&self) -> SegmentIterator<'data, '_, R> {
342 SegmentIterator {
343 inner: map_inner!(self, File, SegmentIteratorInternal, |x| x.segments()),
344 }
345 }
346
347 fn section_by_name_bytes<'file>(
348 &'file self,
349 section_name: &[u8],
350 ) -> Option<Section<'data, 'file, R>> {
351 map_inner_option!(self, File, SectionInternal, |x| x
352 .section_by_name_bytes(section_name))
353 .map(|inner| Section { inner })
354 }
355
356 fn section_by_index(&self, index: SectionIndex) -> Result<Section<'data, '_, R>> {
357 map_inner_option!(self, File, SectionInternal, |x| x.section_by_index(index))
358 .map(|inner| Section { inner })
359 }
360
361 fn sections(&self) -> SectionIterator<'data, '_, R> {
362 SectionIterator {
363 inner: map_inner!(self, File, SectionIteratorInternal, |x| x.sections()),
364 }
365 }
366
367 fn comdats(&self) -> ComdatIterator<'data, '_, R> {
368 ComdatIterator {
369 inner: map_inner!(self, File, ComdatIteratorInternal, |x| x.comdats()),
370 }
371 }
372
373 fn symbol_by_index(&self, index: SymbolIndex) -> Result<Symbol<'data, '_, R>> {
374 map_inner_option!(self, File, SymbolInternal, |x| x
375 .symbol_by_index(index)
376 .map(|x| (x, PhantomData)))
377 .map(|inner| Symbol { inner })
378 }
379
380 fn symbols(&self) -> SymbolIterator<'data, '_, R> {
381 SymbolIterator {
382 inner: map_inner!(self, File, SymbolIteratorInternal, |x| (
383 x.symbols(),
384 PhantomData
385 )),
386 }
387 }
388
389 fn symbol_table(&self) -> Option<SymbolTable<'data, '_, R>> {
390 map_inner_option!(self, File, SymbolTableInternal, |x| x
391 .symbol_table()
392 .map(|x| (x, PhantomData)))
393 .map(|inner| SymbolTable { inner })
394 }
395
396 fn dynamic_symbols(&self) -> SymbolIterator<'data, '_, R> {
397 SymbolIterator {
398 inner: map_inner!(self, File, SymbolIteratorInternal, |x| (
399 x.dynamic_symbols(),
400 PhantomData
401 )),
402 }
403 }
404
405 fn dynamic_symbol_table(&self) -> Option<SymbolTable<'data, '_, R>> {
406 map_inner_option!(self, File, SymbolTableInternal, |x| x
407 .dynamic_symbol_table()
408 .map(|x| (x, PhantomData)))
409 .map(|inner| SymbolTable { inner })
410 }
411
412 #[cfg(feature = "elf")]
413 fn dynamic_relocations(&self) -> Option<DynamicRelocationIterator<'data, '_, R>> {
414 let inner = match self {
415 File::Elf32(ref elf) => {
416 DynamicRelocationIteratorInternal::Elf32(elf.dynamic_relocations()?)
417 }
418 File::Elf64(ref elf) => {
419 DynamicRelocationIteratorInternal::Elf64(elf.dynamic_relocations()?)
420 }
421 #[allow(unreachable_patterns)]
422 _ => return None,
423 };
424 Some(DynamicRelocationIterator { inner })
425 }
426
427 #[cfg(not(feature = "elf"))]
428 fn dynamic_relocations(&self) -> Option<DynamicRelocationIterator<'data, '_, R>> {
429 None
430 }
431
432 fn symbol_map(&self) -> SymbolMap<SymbolMapName<'data>> {
433 with_inner!(self, File, |x| x.symbol_map())
434 }
435
436 fn object_map(&self) -> ObjectMap<'data> {
437 with_inner!(self, File, |x| x.object_map())
438 }
439
440 fn imports(&self) -> Result<Vec<Import<'data>>> {
441 with_inner!(self, File, |x| x.imports())
442 }
443
444 fn exports(&self) -> Result<Vec<Export<'data>>> {
445 with_inner!(self, File, |x| x.exports())
446 }
447
448 fn has_debug_symbols(&self) -> bool {
449 with_inner!(self, File, |x| x.has_debug_symbols())
450 }
451
452 #[inline]
453 fn mach_uuid(&self) -> Result<Option<[u8; 16]>> {
454 with_inner!(self, File, |x| x.mach_uuid())
455 }
456
457 #[inline]
458 fn build_id(&self) -> Result<Option<&'data [u8]>> {
459 with_inner!(self, File, |x| x.build_id())
460 }
461
462 #[inline]
463 fn gnu_debuglink(&self) -> Result<Option<(&'data [u8], u32)>> {
464 with_inner!(self, File, |x| x.gnu_debuglink())
465 }
466
467 #[inline]
468 fn gnu_debugaltlink(&self) -> Result<Option<(&'data [u8], &'data [u8])>> {
469 with_inner!(self, File, |x| x.gnu_debugaltlink())
470 }
471
472 #[inline]
473 fn pdb_info(&self) -> Result<Option<CodeView<'_>>> {
474 with_inner!(self, File, |x| x.pdb_info())
475 }
476
477 fn relative_address_base(&self) -> u64 {
478 with_inner!(self, File, |x| x.relative_address_base())
479 }
480
481 fn entry(&self) -> u64 {
482 with_inner!(self, File, |x| x.entry())
483 }
484
485 fn flags(&self) -> FileFlags {
486 with_inner!(self, File, |x| x.flags())
487 }
488}
489
490#[derive(Debug)]
492pub struct SegmentIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> {
493 inner: SegmentIteratorInternal<'data, 'file, R>,
494}
495
496#[derive(Debug)]
497enum SegmentIteratorInternal<'data, 'file, R: ReadRef<'data>> {
498 #[cfg(feature = "coff")]
499 Coff(coff::CoffSegmentIterator<'data, 'file, R>),
500 #[cfg(feature = "coff")]
501 CoffBig(coff::CoffBigSegmentIterator<'data, 'file, R>),
502 #[cfg(feature = "elf")]
503 Elf32(elf::ElfSegmentIterator32<'data, 'file, Endianness, R>),
504 #[cfg(feature = "elf")]
505 Elf64(elf::ElfSegmentIterator64<'data, 'file, Endianness, R>),
506 #[cfg(feature = "macho")]
507 MachO32(macho::MachOSegmentIterator32<'data, 'file, Endianness, R>),
508 #[cfg(feature = "macho")]
509 MachO64(macho::MachOSegmentIterator64<'data, 'file, Endianness, R>),
510 #[cfg(feature = "pe")]
511 Pe32(pe::PeSegmentIterator32<'data, 'file, R>),
512 #[cfg(feature = "pe")]
513 Pe64(pe::PeSegmentIterator64<'data, 'file, R>),
514 #[cfg(feature = "wasm")]
515 Wasm(wasm::WasmSegmentIterator<'data, 'file, R>),
516 #[cfg(feature = "xcoff")]
517 Xcoff32(xcoff::XcoffSegmentIterator32<'data, 'file, R>),
518 #[cfg(feature = "xcoff")]
519 Xcoff64(xcoff::XcoffSegmentIterator64<'data, 'file, R>),
520}
521
522impl<'data, 'file, R: ReadRef<'data>> Iterator for SegmentIterator<'data, 'file, R> {
523 type Item = Segment<'data, 'file, R>;
524
525 fn next(&mut self) -> Option<Self::Item> {
526 next_inner!(self.inner, SegmentIteratorInternal, SegmentInternal)
527 .map(|inner| Segment { inner })
528 }
529}
530
531pub struct Segment<'data, 'file, R: ReadRef<'data> = &'data [u8]> {
535 inner: SegmentInternal<'data, 'file, R>,
536}
537
538#[derive(Debug)]
539enum SegmentInternal<'data, 'file, R: ReadRef<'data>> {
540 #[cfg(feature = "coff")]
541 Coff(coff::CoffSegment<'data, 'file, R>),
542 #[cfg(feature = "coff")]
543 CoffBig(coff::CoffBigSegment<'data, 'file, R>),
544 #[cfg(feature = "elf")]
545 Elf32(elf::ElfSegment32<'data, 'file, Endianness, R>),
546 #[cfg(feature = "elf")]
547 Elf64(elf::ElfSegment64<'data, 'file, Endianness, R>),
548 #[cfg(feature = "macho")]
549 MachO32(macho::MachOSegment32<'data, 'file, Endianness, R>),
550 #[cfg(feature = "macho")]
551 MachO64(macho::MachOSegment64<'data, 'file, Endianness, R>),
552 #[cfg(feature = "pe")]
553 Pe32(pe::PeSegment32<'data, 'file, R>),
554 #[cfg(feature = "pe")]
555 Pe64(pe::PeSegment64<'data, 'file, R>),
556 #[cfg(feature = "wasm")]
557 Wasm(wasm::WasmSegment<'data, 'file, R>),
558 #[cfg(feature = "xcoff")]
559 Xcoff32(xcoff::XcoffSegment32<'data, 'file, R>),
560 #[cfg(feature = "xcoff")]
561 Xcoff64(xcoff::XcoffSegment64<'data, 'file, R>),
562}
563
564impl<'data, 'file, R: ReadRef<'data>> fmt::Debug for Segment<'data, 'file, R> {
565 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
566 let mut s = f.debug_struct("Segment");
568 match self.name() {
569 Ok(Some(ref name)) => {
570 s.field("name", name);
571 }
572 Ok(None) => {}
573 Err(_) => {
574 s.field("name", &"<invalid>");
575 }
576 }
577 s.field("address", &self.address())
578 .field("size", &self.size())
579 .finish()
580 }
581}
582
583impl<'data, 'file, R: ReadRef<'data>> read::private::Sealed for Segment<'data, 'file, R> {}
584
585impl<'data, 'file, R: ReadRef<'data>> ObjectSegment<'data> for Segment<'data, 'file, R> {
586 fn address(&self) -> u64 {
587 with_inner!(self.inner, SegmentInternal, |x| x.address())
588 }
589
590 fn size(&self) -> u64 {
591 with_inner!(self.inner, SegmentInternal, |x| x.size())
592 }
593
594 fn align(&self) -> u64 {
595 with_inner!(self.inner, SegmentInternal, |x| x.align())
596 }
597
598 fn file_range(&self) -> (u64, u64) {
599 with_inner!(self.inner, SegmentInternal, |x| x.file_range())
600 }
601
602 fn data(&self) -> Result<&'data [u8]> {
603 with_inner!(self.inner, SegmentInternal, |x| x.data())
604 }
605
606 fn data_range(&self, address: u64, size: u64) -> Result<Option<&'data [u8]>> {
607 with_inner!(self.inner, SegmentInternal, |x| x.data_range(address, size))
608 }
609
610 fn name_bytes(&self) -> Result<Option<&[u8]>> {
611 with_inner!(self.inner, SegmentInternal, |x| x.name_bytes())
612 }
613
614 fn name(&self) -> Result<Option<&str>> {
615 with_inner!(self.inner, SegmentInternal, |x| x.name())
616 }
617
618 fn flags(&self) -> SegmentFlags {
619 with_inner!(self.inner, SegmentInternal, |x| x.flags())
620 }
621}
622
623#[derive(Debug)]
625pub struct SectionIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> {
626 inner: SectionIteratorInternal<'data, 'file, R>,
627}
628
629#[derive(Debug)]
631enum SectionIteratorInternal<'data, 'file, R: ReadRef<'data>> {
632 #[cfg(feature = "coff")]
633 Coff(coff::CoffSectionIterator<'data, 'file, R>),
634 #[cfg(feature = "coff")]
635 CoffBig(coff::CoffBigSectionIterator<'data, 'file, R>),
636 #[cfg(feature = "elf")]
637 Elf32(elf::ElfSectionIterator32<'data, 'file, Endianness, R>),
638 #[cfg(feature = "elf")]
639 Elf64(elf::ElfSectionIterator64<'data, 'file, Endianness, R>),
640 #[cfg(feature = "macho")]
641 MachO32(macho::MachOSectionIterator32<'data, 'file, Endianness, R>),
642 #[cfg(feature = "macho")]
643 MachO64(macho::MachOSectionIterator64<'data, 'file, Endianness, R>),
644 #[cfg(feature = "pe")]
645 Pe32(pe::PeSectionIterator32<'data, 'file, R>),
646 #[cfg(feature = "pe")]
647 Pe64(pe::PeSectionIterator64<'data, 'file, R>),
648 #[cfg(feature = "wasm")]
649 Wasm(wasm::WasmSectionIterator<'data, 'file, R>),
650 #[cfg(feature = "xcoff")]
651 Xcoff32(xcoff::XcoffSectionIterator32<'data, 'file, R>),
652 #[cfg(feature = "xcoff")]
653 Xcoff64(xcoff::XcoffSectionIterator64<'data, 'file, R>),
654}
655
656impl<'data, 'file, R: ReadRef<'data>> Iterator for SectionIterator<'data, 'file, R> {
657 type Item = Section<'data, 'file, R>;
658
659 fn next(&mut self) -> Option<Self::Item> {
660 next_inner!(self.inner, SectionIteratorInternal, SectionInternal)
661 .map(|inner| Section { inner })
662 }
663}
664
665pub struct Section<'data, 'file, R: ReadRef<'data> = &'data [u8]> {
669 inner: SectionInternal<'data, 'file, R>,
670}
671
672enum SectionInternal<'data, 'file, R: ReadRef<'data>> {
673 #[cfg(feature = "coff")]
674 Coff(coff::CoffSection<'data, 'file, R>),
675 #[cfg(feature = "coff")]
676 CoffBig(coff::CoffBigSection<'data, 'file, R>),
677 #[cfg(feature = "elf")]
678 Elf32(elf::ElfSection32<'data, 'file, Endianness, R>),
679 #[cfg(feature = "elf")]
680 Elf64(elf::ElfSection64<'data, 'file, Endianness, R>),
681 #[cfg(feature = "macho")]
682 MachO32(macho::MachOSection32<'data, 'file, Endianness, R>),
683 #[cfg(feature = "macho")]
684 MachO64(macho::MachOSection64<'data, 'file, Endianness, R>),
685 #[cfg(feature = "pe")]
686 Pe32(pe::PeSection32<'data, 'file, R>),
687 #[cfg(feature = "pe")]
688 Pe64(pe::PeSection64<'data, 'file, R>),
689 #[cfg(feature = "wasm")]
690 Wasm(wasm::WasmSection<'data, 'file, R>),
691 #[cfg(feature = "xcoff")]
692 Xcoff32(xcoff::XcoffSection32<'data, 'file, R>),
693 #[cfg(feature = "xcoff")]
694 Xcoff64(xcoff::XcoffSection64<'data, 'file, R>),
695}
696
697impl<'data, 'file, R: ReadRef<'data>> fmt::Debug for Section<'data, 'file, R> {
698 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
699 let mut s = f.debug_struct("Section");
701 match self.segment_name() {
702 Ok(Some(ref name)) => {
703 s.field("segment", name);
704 }
705 Ok(None) => {}
706 Err(_) => {
707 s.field("segment", &"<invalid>");
708 }
709 }
710 s.field("name", &self.name().unwrap_or("<invalid>"))
711 .field("address", &self.address())
712 .field("size", &self.size())
713 .field("align", &self.align())
714 .field("kind", &self.kind())
715 .field("flags", &self.flags())
716 .finish()
717 }
718}
719
720impl<'data, 'file, R: ReadRef<'data>> read::private::Sealed for Section<'data, 'file, R> {}
721
722impl<'data, 'file, R: ReadRef<'data>> ObjectSection<'data> for Section<'data, 'file, R> {
723 type RelocationIterator = SectionRelocationIterator<'data, 'file, R>;
724
725 fn index(&self) -> SectionIndex {
726 with_inner!(self.inner, SectionInternal, |x| x.index())
727 }
728
729 fn address(&self) -> u64 {
730 with_inner!(self.inner, SectionInternal, |x| x.address())
731 }
732
733 fn size(&self) -> u64 {
734 with_inner!(self.inner, SectionInternal, |x| x.size())
735 }
736
737 fn align(&self) -> u64 {
738 with_inner!(self.inner, SectionInternal, |x| x.align())
739 }
740
741 fn file_range(&self) -> Option<(u64, u64)> {
742 with_inner!(self.inner, SectionInternal, |x| x.file_range())
743 }
744
745 fn data(&self) -> Result<&'data [u8]> {
746 with_inner!(self.inner, SectionInternal, |x| x.data())
747 }
748
749 fn data_range(&self, address: u64, size: u64) -> Result<Option<&'data [u8]>> {
750 with_inner!(self.inner, SectionInternal, |x| x.data_range(address, size))
751 }
752
753 fn compressed_file_range(&self) -> Result<CompressedFileRange> {
754 with_inner!(self.inner, SectionInternal, |x| x.compressed_file_range())
755 }
756
757 fn compressed_data(&self) -> Result<CompressedData<'data>> {
758 with_inner!(self.inner, SectionInternal, |x| x.compressed_data())
759 }
760
761 fn name_bytes(&self) -> Result<&'data [u8]> {
762 with_inner!(self.inner, SectionInternal, |x| x.name_bytes())
763 }
764
765 fn name(&self) -> Result<&'data str> {
766 with_inner!(self.inner, SectionInternal, |x| x.name())
767 }
768
769 fn segment_name_bytes(&self) -> Result<Option<&[u8]>> {
770 with_inner!(self.inner, SectionInternal, |x| x.segment_name_bytes())
771 }
772
773 fn segment_name(&self) -> Result<Option<&str>> {
774 with_inner!(self.inner, SectionInternal, |x| x.segment_name())
775 }
776
777 fn kind(&self) -> SectionKind {
778 with_inner!(self.inner, SectionInternal, |x| x.kind())
779 }
780
781 fn relocations(&self) -> SectionRelocationIterator<'data, 'file, R> {
782 SectionRelocationIterator {
783 inner: map_inner!(
784 self.inner,
785 SectionInternal,
786 SectionRelocationIteratorInternal,
787 |x| x.relocations()
788 ),
789 }
790 }
791
792 fn relocation_map(&self) -> Result<RelocationMap> {
793 with_inner!(self.inner, SectionInternal, |x| x.relocation_map())
794 }
795
796 fn flags(&self) -> SectionFlags {
797 with_inner!(self.inner, SectionInternal, |x| x.flags())
798 }
799}
800
801#[derive(Debug)]
803pub struct ComdatIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> {
804 inner: ComdatIteratorInternal<'data, 'file, R>,
805}
806
807#[derive(Debug)]
808enum ComdatIteratorInternal<'data, 'file, R: ReadRef<'data>> {
809 #[cfg(feature = "coff")]
810 Coff(coff::CoffComdatIterator<'data, 'file, R>),
811 #[cfg(feature = "coff")]
812 CoffBig(coff::CoffBigComdatIterator<'data, 'file, R>),
813 #[cfg(feature = "elf")]
814 Elf32(elf::ElfComdatIterator32<'data, 'file, Endianness, R>),
815 #[cfg(feature = "elf")]
816 Elf64(elf::ElfComdatIterator64<'data, 'file, Endianness, R>),
817 #[cfg(feature = "macho")]
818 MachO32(macho::MachOComdatIterator32<'data, 'file, Endianness, R>),
819 #[cfg(feature = "macho")]
820 MachO64(macho::MachOComdatIterator64<'data, 'file, Endianness, R>),
821 #[cfg(feature = "pe")]
822 Pe32(pe::PeComdatIterator32<'data, 'file, R>),
823 #[cfg(feature = "pe")]
824 Pe64(pe::PeComdatIterator64<'data, 'file, R>),
825 #[cfg(feature = "wasm")]
826 Wasm(wasm::WasmComdatIterator<'data, 'file, R>),
827 #[cfg(feature = "xcoff")]
828 Xcoff32(xcoff::XcoffComdatIterator32<'data, 'file, R>),
829 #[cfg(feature = "xcoff")]
830 Xcoff64(xcoff::XcoffComdatIterator64<'data, 'file, R>),
831}
832
833impl<'data, 'file, R: ReadRef<'data>> Iterator for ComdatIterator<'data, 'file, R> {
834 type Item = Comdat<'data, 'file, R>;
835
836 fn next(&mut self) -> Option<Self::Item> {
837 next_inner!(self.inner, ComdatIteratorInternal, ComdatInternal)
838 .map(|inner| Comdat { inner })
839 }
840}
841
842pub struct Comdat<'data, 'file, R: ReadRef<'data> = &'data [u8]> {
846 inner: ComdatInternal<'data, 'file, R>,
847}
848
849enum ComdatInternal<'data, 'file, R: ReadRef<'data>> {
850 #[cfg(feature = "coff")]
851 Coff(coff::CoffComdat<'data, 'file, R>),
852 #[cfg(feature = "coff")]
853 CoffBig(coff::CoffBigComdat<'data, 'file, R>),
854 #[cfg(feature = "elf")]
855 Elf32(elf::ElfComdat32<'data, 'file, Endianness, R>),
856 #[cfg(feature = "elf")]
857 Elf64(elf::ElfComdat64<'data, 'file, Endianness, R>),
858 #[cfg(feature = "macho")]
859 MachO32(macho::MachOComdat32<'data, 'file, Endianness, R>),
860 #[cfg(feature = "macho")]
861 MachO64(macho::MachOComdat64<'data, 'file, Endianness, R>),
862 #[cfg(feature = "pe")]
863 Pe32(pe::PeComdat32<'data, 'file, R>),
864 #[cfg(feature = "pe")]
865 Pe64(pe::PeComdat64<'data, 'file, R>),
866 #[cfg(feature = "wasm")]
867 Wasm(wasm::WasmComdat<'data, 'file, R>),
868 #[cfg(feature = "xcoff")]
869 Xcoff32(xcoff::XcoffComdat32<'data, 'file, R>),
870 #[cfg(feature = "xcoff")]
871 Xcoff64(xcoff::XcoffComdat64<'data, 'file, R>),
872}
873
874impl<'data, 'file, R: ReadRef<'data>> fmt::Debug for Comdat<'data, 'file, R> {
875 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
876 let mut s = f.debug_struct("Comdat");
877 s.field("symbol", &self.symbol())
878 .field("name", &self.name().unwrap_or("<invalid>"))
879 .field("kind", &self.kind())
880 .finish()
881 }
882}
883
884impl<'data, 'file, R: ReadRef<'data>> read::private::Sealed for Comdat<'data, 'file, R> {}
885
886impl<'data, 'file, R: ReadRef<'data>> ObjectComdat<'data> for Comdat<'data, 'file, R> {
887 type SectionIterator = ComdatSectionIterator<'data, 'file, R>;
888
889 fn kind(&self) -> ComdatKind {
890 with_inner!(self.inner, ComdatInternal, |x| x.kind())
891 }
892
893 fn symbol(&self) -> SymbolIndex {
894 with_inner!(self.inner, ComdatInternal, |x| x.symbol())
895 }
896
897 fn name_bytes(&self) -> Result<&'data [u8]> {
898 with_inner!(self.inner, ComdatInternal, |x| x.name_bytes())
899 }
900
901 fn name(&self) -> Result<&'data str> {
902 with_inner!(self.inner, ComdatInternal, |x| x.name())
903 }
904
905 fn sections(&self) -> ComdatSectionIterator<'data, 'file, R> {
906 ComdatSectionIterator {
907 inner: map_inner!(
908 self.inner,
909 ComdatInternal,
910 ComdatSectionIteratorInternal,
911 |x| x.sections()
912 ),
913 }
914 }
915}
916
917#[derive(Debug)]
919pub struct ComdatSectionIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> {
920 inner: ComdatSectionIteratorInternal<'data, 'file, R>,
921}
922
923#[derive(Debug)]
924enum ComdatSectionIteratorInternal<'data, 'file, R: ReadRef<'data>> {
925 #[cfg(feature = "coff")]
926 Coff(coff::CoffComdatSectionIterator<'data, 'file, R>),
927 #[cfg(feature = "coff")]
928 CoffBig(coff::CoffBigComdatSectionIterator<'data, 'file, R>),
929 #[cfg(feature = "elf")]
930 Elf32(elf::ElfComdatSectionIterator32<'data, 'file, Endianness, R>),
931 #[cfg(feature = "elf")]
932 Elf64(elf::ElfComdatSectionIterator64<'data, 'file, Endianness, R>),
933 #[cfg(feature = "macho")]
934 MachO32(macho::MachOComdatSectionIterator32<'data, 'file, Endianness, R>),
935 #[cfg(feature = "macho")]
936 MachO64(macho::MachOComdatSectionIterator64<'data, 'file, Endianness, R>),
937 #[cfg(feature = "pe")]
938 Pe32(pe::PeComdatSectionIterator32<'data, 'file, R>),
939 #[cfg(feature = "pe")]
940 Pe64(pe::PeComdatSectionIterator64<'data, 'file, R>),
941 #[cfg(feature = "wasm")]
942 Wasm(wasm::WasmComdatSectionIterator<'data, 'file, R>),
943 #[cfg(feature = "xcoff")]
944 Xcoff32(xcoff::XcoffComdatSectionIterator32<'data, 'file, R>),
945 #[cfg(feature = "xcoff")]
946 Xcoff64(xcoff::XcoffComdatSectionIterator64<'data, 'file, R>),
947}
948
949impl<'data, 'file, R: ReadRef<'data>> Iterator for ComdatSectionIterator<'data, 'file, R> {
950 type Item = SectionIndex;
951
952 fn next(&mut self) -> Option<Self::Item> {
953 with_inner_mut!(self.inner, ComdatSectionIteratorInternal, |x| x.next())
954 }
955}
956
957#[derive(Debug)]
961pub struct SymbolTable<'data, 'file, R = &'data [u8]>
962where
963 R: ReadRef<'data>,
964{
965 inner: SymbolTableInternal<'data, 'file, R>,
966}
967
968#[derive(Debug)]
969enum SymbolTableInternal<'data, 'file, R>
970where
971 R: ReadRef<'data>,
972{
973 #[cfg(feature = "coff")]
974 Coff((coff::CoffSymbolTable<'data, 'file, R>, PhantomData<R>)),
975 #[cfg(feature = "coff")]
976 CoffBig((coff::CoffBigSymbolTable<'data, 'file, R>, PhantomData<R>)),
977 #[cfg(feature = "elf")]
978 Elf32(
979 (
980 elf::ElfSymbolTable32<'data, 'file, Endianness, R>,
981 PhantomData<R>,
982 ),
983 ),
984 #[cfg(feature = "elf")]
985 Elf64(
986 (
987 elf::ElfSymbolTable64<'data, 'file, Endianness, R>,
988 PhantomData<R>,
989 ),
990 ),
991 #[cfg(feature = "macho")]
992 MachO32(
993 (
994 macho::MachOSymbolTable32<'data, 'file, Endianness, R>,
995 PhantomData<()>,
996 ),
997 ),
998 #[cfg(feature = "macho")]
999 MachO64(
1000 (
1001 macho::MachOSymbolTable64<'data, 'file, Endianness, R>,
1002 PhantomData<()>,
1003 ),
1004 ),
1005 #[cfg(feature = "pe")]
1006 Pe32((coff::CoffSymbolTable<'data, 'file, R>, PhantomData<R>)),
1007 #[cfg(feature = "pe")]
1008 Pe64((coff::CoffSymbolTable<'data, 'file, R>, PhantomData<R>)),
1009 #[cfg(feature = "wasm")]
1010 Wasm((wasm::WasmSymbolTable<'data, 'file>, PhantomData<R>)),
1011 #[cfg(feature = "xcoff")]
1012 Xcoff32((xcoff::XcoffSymbolTable32<'data, 'file, R>, PhantomData<R>)),
1013 #[cfg(feature = "xcoff")]
1014 Xcoff64((xcoff::XcoffSymbolTable64<'data, 'file, R>, PhantomData<R>)),
1015}
1016
1017impl<'data, 'file, R: ReadRef<'data>> read::private::Sealed for SymbolTable<'data, 'file, R> {}
1018
1019impl<'data, 'file, R: ReadRef<'data>> ObjectSymbolTable<'data> for SymbolTable<'data, 'file, R> {
1020 type Symbol = Symbol<'data, 'file, R>;
1021 type SymbolIterator = SymbolIterator<'data, 'file, R>;
1022
1023 fn symbols(&self) -> Self::SymbolIterator {
1024 SymbolIterator {
1025 inner: map_inner!(
1026 self.inner,
1027 SymbolTableInternal,
1028 SymbolIteratorInternal,
1029 |x| (x.0.symbols(), PhantomData)
1030 ),
1031 }
1032 }
1033
1034 fn symbol_by_index(&self, index: SymbolIndex) -> Result<Self::Symbol> {
1035 map_inner_option!(self.inner, SymbolTableInternal, SymbolInternal, |x| x
1036 .0
1037 .symbol_by_index(index)
1038 .map(|x| (x, PhantomData)))
1039 .map(|inner| Symbol { inner })
1040 }
1041}
1042
1043#[derive(Debug)]
1045pub struct SymbolIterator<'data, 'file, R = &'data [u8]>
1046where
1047 R: ReadRef<'data>,
1048{
1049 inner: SymbolIteratorInternal<'data, 'file, R>,
1050}
1051
1052#[derive(Debug)]
1053enum SymbolIteratorInternal<'data, 'file, R>
1054where
1055 R: ReadRef<'data>,
1056{
1057 #[cfg(feature = "coff")]
1058 Coff((coff::CoffSymbolIterator<'data, 'file, R>, PhantomData<R>)),
1059 #[cfg(feature = "coff")]
1060 CoffBig((coff::CoffBigSymbolIterator<'data, 'file, R>, PhantomData<R>)),
1061 #[cfg(feature = "elf")]
1062 Elf32(
1063 (
1064 elf::ElfSymbolIterator32<'data, 'file, Endianness, R>,
1065 PhantomData<R>,
1066 ),
1067 ),
1068 #[cfg(feature = "elf")]
1069 Elf64(
1070 (
1071 elf::ElfSymbolIterator64<'data, 'file, Endianness, R>,
1072 PhantomData<R>,
1073 ),
1074 ),
1075 #[cfg(feature = "macho")]
1076 MachO32(
1077 (
1078 macho::MachOSymbolIterator32<'data, 'file, Endianness, R>,
1079 PhantomData<()>,
1080 ),
1081 ),
1082 #[cfg(feature = "macho")]
1083 MachO64(
1084 (
1085 macho::MachOSymbolIterator64<'data, 'file, Endianness, R>,
1086 PhantomData<()>,
1087 ),
1088 ),
1089 #[cfg(feature = "pe")]
1090 Pe32((coff::CoffSymbolIterator<'data, 'file, R>, PhantomData<R>)),
1091 #[cfg(feature = "pe")]
1092 Pe64((coff::CoffSymbolIterator<'data, 'file, R>, PhantomData<R>)),
1093 #[cfg(feature = "wasm")]
1094 Wasm((wasm::WasmSymbolIterator<'data, 'file>, PhantomData<R>)),
1095 #[cfg(feature = "xcoff")]
1096 Xcoff32(
1097 (
1098 xcoff::XcoffSymbolIterator32<'data, 'file, R>,
1099 PhantomData<R>,
1100 ),
1101 ),
1102 #[cfg(feature = "xcoff")]
1103 Xcoff64(
1104 (
1105 xcoff::XcoffSymbolIterator64<'data, 'file, R>,
1106 PhantomData<R>,
1107 ),
1108 ),
1109}
1110
1111impl<'data, 'file, R: ReadRef<'data>> Iterator for SymbolIterator<'data, 'file, R> {
1112 type Item = Symbol<'data, 'file, R>;
1113
1114 fn next(&mut self) -> Option<Self::Item> {
1115 map_inner_option_mut!(self.inner, SymbolIteratorInternal, SymbolInternal, |iter| {
1116 iter.0.next().map(|x| (x, PhantomData))
1117 })
1118 .map(|inner| Symbol { inner })
1119 }
1120}
1121
1122pub struct Symbol<'data, 'file, R = &'data [u8]>
1126where
1127 R: ReadRef<'data>,
1128{
1129 inner: SymbolInternal<'data, 'file, R>,
1130}
1131
1132enum SymbolInternal<'data, 'file, R>
1133where
1134 R: ReadRef<'data>,
1135{
1136 #[cfg(feature = "coff")]
1137 Coff((coff::CoffSymbol<'data, 'file, R>, PhantomData<R>)),
1138 #[cfg(feature = "coff")]
1139 CoffBig((coff::CoffBigSymbol<'data, 'file, R>, PhantomData<R>)),
1140 #[cfg(feature = "elf")]
1141 Elf32(
1142 (
1143 elf::ElfSymbol32<'data, 'file, Endianness, R>,
1144 PhantomData<R>,
1145 ),
1146 ),
1147 #[cfg(feature = "elf")]
1148 Elf64(
1149 (
1150 elf::ElfSymbol64<'data, 'file, Endianness, R>,
1151 PhantomData<R>,
1152 ),
1153 ),
1154 #[cfg(feature = "macho")]
1155 MachO32(
1156 (
1157 macho::MachOSymbol32<'data, 'file, Endianness, R>,
1158 PhantomData<()>,
1159 ),
1160 ),
1161 #[cfg(feature = "macho")]
1162 MachO64(
1163 (
1164 macho::MachOSymbol64<'data, 'file, Endianness, R>,
1165 PhantomData<()>,
1166 ),
1167 ),
1168 #[cfg(feature = "pe")]
1169 Pe32((coff::CoffSymbol<'data, 'file, R>, PhantomData<R>)),
1170 #[cfg(feature = "pe")]
1171 Pe64((coff::CoffSymbol<'data, 'file, R>, PhantomData<R>)),
1172 #[cfg(feature = "wasm")]
1173 Wasm((wasm::WasmSymbol<'data, 'file>, PhantomData<R>)),
1174 #[cfg(feature = "xcoff")]
1175 Xcoff32((xcoff::XcoffSymbol32<'data, 'file, R>, PhantomData<R>)),
1176 #[cfg(feature = "xcoff")]
1177 Xcoff64((xcoff::XcoffSymbol64<'data, 'file, R>, PhantomData<R>)),
1178}
1179
1180impl<'data, 'file, R: ReadRef<'data>> fmt::Debug for Symbol<'data, 'file, R> {
1181 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1182 f.debug_struct("Symbol")
1183 .field("name", &self.name().unwrap_or("<invalid>"))
1184 .field("address", &self.address())
1185 .field("size", &self.size())
1186 .field("kind", &self.kind())
1187 .field("section", &self.section())
1188 .field("scope", &self.scope())
1189 .field("weak", &self.is_weak())
1190 .field("flags", &self.flags())
1191 .finish()
1192 }
1193}
1194
1195impl<'data, 'file, R: ReadRef<'data>> read::private::Sealed for Symbol<'data, 'file, R> {}
1196
1197impl<'data, 'file, R: ReadRef<'data>> ObjectSymbol<'data> for Symbol<'data, 'file, R> {
1198 fn index(&self) -> SymbolIndex {
1199 with_inner!(self.inner, SymbolInternal, |x| x.0.index())
1200 }
1201
1202 fn name_bytes(&self) -> Result<&'data [u8]> {
1203 with_inner!(self.inner, SymbolInternal, |x| x.0.name_bytes())
1204 }
1205
1206 fn name(&self) -> Result<&'data str> {
1207 with_inner!(self.inner, SymbolInternal, |x| x.0.name())
1208 }
1209
1210 fn address(&self) -> u64 {
1211 with_inner!(self.inner, SymbolInternal, |x| x.0.address())
1212 }
1213
1214 fn size(&self) -> u64 {
1215 with_inner!(self.inner, SymbolInternal, |x| x.0.size())
1216 }
1217
1218 fn kind(&self) -> SymbolKind {
1219 with_inner!(self.inner, SymbolInternal, |x| x.0.kind())
1220 }
1221
1222 fn section(&self) -> SymbolSection {
1223 with_inner!(self.inner, SymbolInternal, |x| x.0.section())
1224 }
1225
1226 fn is_undefined(&self) -> bool {
1227 with_inner!(self.inner, SymbolInternal, |x| x.0.is_undefined())
1228 }
1229
1230 fn is_definition(&self) -> bool {
1231 with_inner!(self.inner, SymbolInternal, |x| x.0.is_definition())
1232 }
1233
1234 fn is_common(&self) -> bool {
1235 with_inner!(self.inner, SymbolInternal, |x| x.0.is_common())
1236 }
1237
1238 fn is_weak(&self) -> bool {
1239 with_inner!(self.inner, SymbolInternal, |x| x.0.is_weak())
1240 }
1241
1242 fn scope(&self) -> SymbolScope {
1243 with_inner!(self.inner, SymbolInternal, |x| x.0.scope())
1244 }
1245
1246 fn is_global(&self) -> bool {
1247 with_inner!(self.inner, SymbolInternal, |x| x.0.is_global())
1248 }
1249
1250 fn is_local(&self) -> bool {
1251 with_inner!(self.inner, SymbolInternal, |x| x.0.is_local())
1252 }
1253
1254 fn flags(&self) -> SymbolFlags<SectionIndex, SymbolIndex> {
1255 with_inner!(self.inner, SymbolInternal, |x| x.0.flags())
1256 }
1257}
1258
1259#[derive(Debug)]
1261pub struct DynamicRelocationIterator<'data, 'file, R = &'data [u8]>
1262where
1263 R: ReadRef<'data>,
1264{
1265 inner: DynamicRelocationIteratorInternal<'data, 'file, R>,
1266}
1267
1268#[derive(Debug)]
1269enum DynamicRelocationIteratorInternal<'data, 'file, R>
1270where
1271 R: ReadRef<'data>,
1272{
1273 #[cfg(feature = "elf")]
1274 Elf32(elf::ElfDynamicRelocationIterator32<'data, 'file, Endianness, R>),
1275 #[cfg(feature = "elf")]
1276 Elf64(elf::ElfDynamicRelocationIterator64<'data, 'file, Endianness, R>),
1277 #[allow(unused)]
1279 None(PhantomData<(&'data (), &'file (), R)>),
1280}
1281
1282impl<'data, 'file, R: ReadRef<'data>> Iterator for DynamicRelocationIterator<'data, 'file, R> {
1283 type Item = (u64, Relocation);
1284
1285 fn next(&mut self) -> Option<Self::Item> {
1286 match self.inner {
1287 #[cfg(feature = "elf")]
1288 DynamicRelocationIteratorInternal::Elf32(ref mut elf) => elf.next(),
1289 #[cfg(feature = "elf")]
1290 DynamicRelocationIteratorInternal::Elf64(ref mut elf) => elf.next(),
1291 DynamicRelocationIteratorInternal::None(_) => None,
1292 }
1293 }
1294}
1295
1296#[derive(Debug)]
1298pub struct SectionRelocationIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> {
1299 inner: SectionRelocationIteratorInternal<'data, 'file, R>,
1300}
1301
1302#[derive(Debug)]
1303enum SectionRelocationIteratorInternal<'data, 'file, R: ReadRef<'data>> {
1304 #[cfg(feature = "coff")]
1305 Coff(coff::CoffRelocationIterator<'data, 'file, R>),
1306 #[cfg(feature = "coff")]
1307 CoffBig(coff::CoffBigRelocationIterator<'data, 'file, R>),
1308 #[cfg(feature = "elf")]
1309 Elf32(elf::ElfSectionRelocationIterator32<'data, 'file, Endianness, R>),
1310 #[cfg(feature = "elf")]
1311 Elf64(elf::ElfSectionRelocationIterator64<'data, 'file, Endianness, R>),
1312 #[cfg(feature = "macho")]
1313 MachO32(macho::MachORelocationIterator32<'data, 'file, Endianness, R>),
1314 #[cfg(feature = "macho")]
1315 MachO64(macho::MachORelocationIterator64<'data, 'file, Endianness, R>),
1316 #[cfg(feature = "pe")]
1317 Pe32(pe::PeRelocationIterator<'data, 'file, R>),
1318 #[cfg(feature = "pe")]
1319 Pe64(pe::PeRelocationIterator<'data, 'file, R>),
1320 #[cfg(feature = "wasm")]
1321 Wasm(wasm::WasmRelocationIterator<'data, 'file, R>),
1322 #[cfg(feature = "xcoff")]
1323 Xcoff32(xcoff::XcoffRelocationIterator32<'data, 'file, R>),
1324 #[cfg(feature = "xcoff")]
1325 Xcoff64(xcoff::XcoffRelocationIterator64<'data, 'file, R>),
1326}
1327
1328impl<'data, 'file, R: ReadRef<'data>> Iterator for SectionRelocationIterator<'data, 'file, R> {
1329 type Item = (u64, Relocation);
1330
1331 fn next(&mut self) -> Option<Self::Item> {
1332 with_inner_mut!(self.inner, SectionRelocationIteratorInternal, |x| x.next())
1333 }
1334}