3 #[cfg(feature = "coff")]
5 #[cfg(feature = "elf")]
7 #[cfg(feature = "macho")]
8 use crate::read
::macho
;
11 #[cfg(feature = "wasm")]
12 use crate::read
::wasm
;
14 self, Architecture
, BinaryFormat
, ComdatKind
, CompressedData
, Error
, FileFlags
, Object
,
15 ObjectComdat
, ObjectMap
, ObjectSection
, ObjectSegment
, ObjectSymbol
, ObjectSymbolTable
,
16 Relocation
, Result
, SectionFlags
, SectionIndex
, SectionKind
, SymbolFlags
, SymbolIndex
,
17 SymbolKind
, SymbolMap
, SymbolMapName
, SymbolScope
, SymbolSection
,
20 /// Evaluate an expression on the contents of a file format enum.
22 /// This is a hack to avoid virtual calls.
23 macro_rules
! with_inner
{
24 ($inner
:expr
, $
enum:ident
, | $var
:ident
| $body
:expr
) => {
26 #[cfg(feature = "coff")]
27 $
enum::Coff(ref $var
) => $body
,
28 #[cfg(feature = "elf")]
29 $
enum::Elf32(ref $var
) => $body
,
30 #[cfg(feature = "elf")]
31 $
enum::Elf64(ref $var
) => $body
,
32 #[cfg(feature = "macho")]
33 $
enum::MachO32(ref $var
) => $body
,
34 #[cfg(feature = "macho")]
35 $
enum::MachO64(ref $var
) => $body
,
36 #[cfg(feature = "pe")]
37 $
enum::Pe32(ref $var
) => $body
,
38 #[cfg(feature = "pe")]
39 $
enum::Pe64(ref $var
) => $body
,
40 #[cfg(feature = "wasm")]
41 $
enum::Wasm(ref $var
) => $body
,
46 macro_rules
! with_inner_mut
{
47 ($inner
:expr
, $
enum:ident
, | $var
:ident
| $body
:expr
) => {
49 #[cfg(feature = "coff")]
50 $
enum::Coff(ref mut $var
) => $body
,
51 #[cfg(feature = "elf")]
52 $
enum::Elf32(ref mut $var
) => $body
,
53 #[cfg(feature = "elf")]
54 $
enum::Elf64(ref mut $var
) => $body
,
55 #[cfg(feature = "macho")]
56 $
enum::MachO32(ref mut $var
) => $body
,
57 #[cfg(feature = "macho")]
58 $
enum::MachO64(ref mut $var
) => $body
,
59 #[cfg(feature = "pe")]
60 $
enum::Pe32(ref mut $var
) => $body
,
61 #[cfg(feature = "pe")]
62 $
enum::Pe64(ref mut $var
) => $body
,
63 #[cfg(feature = "wasm")]
64 $
enum::Wasm(ref mut $var
) => $body
,
69 /// Like `with_inner!`, but wraps the result in another enum.
70 macro_rules
! map_inner
{
71 ($inner
:expr
, $from
:ident
, $to
:ident
, | $var
:ident
| $body
:expr
) => {
73 #[cfg(feature = "coff")]
74 $from
::Coff(ref $var
) => $to
::Coff($body
),
75 #[cfg(feature = "elf")]
76 $from
::Elf32(ref $var
) => $to
::Elf32($body
),
77 #[cfg(feature = "elf")]
78 $from
::Elf64(ref $var
) => $to
::Elf64($body
),
79 #[cfg(feature = "macho")]
80 $from
::MachO32(ref $var
) => $to
::MachO32($body
),
81 #[cfg(feature = "macho")]
82 $from
::MachO64(ref $var
) => $to
::MachO64($body
),
83 #[cfg(feature = "pe")]
84 $from
::Pe32(ref $var
) => $to
::Pe32($body
),
85 #[cfg(feature = "pe")]
86 $from
::Pe64(ref $var
) => $to
::Pe64($body
),
87 #[cfg(feature = "wasm")]
88 $from
::Wasm(ref $var
) => $to
::Wasm($body
),
93 /// Like `map_inner!`, but the result is a Result or Option.
94 macro_rules
! map_inner_option
{
95 ($inner
:expr
, $from
:ident
, $to
:ident
, | $var
:ident
| $body
:expr
) => {
97 #[cfg(feature = "coff")]
98 $from
::Coff(ref $var
) => $body
.map($to
::Coff
),
99 #[cfg(feature = "elf")]
100 $from
::Elf32(ref $var
) => $body
.map($to
::Elf32
),
101 #[cfg(feature = "elf")]
102 $from
::Elf64(ref $var
) => $body
.map($to
::Elf64
),
103 #[cfg(feature = "macho")]
104 $from
::MachO32(ref $var
) => $body
.map($to
::MachO32
),
105 #[cfg(feature = "macho")]
106 $from
::MachO64(ref $var
) => $body
.map($to
::MachO64
),
107 #[cfg(feature = "pe")]
108 $from
::Pe32(ref $var
) => $body
.map($to
::Pe32
),
109 #[cfg(feature = "pe")]
110 $from
::Pe64(ref $var
) => $body
.map($to
::Pe64
),
111 #[cfg(feature = "wasm")]
112 $from
::Wasm(ref $var
) => $body
.map($to
::Wasm
),
117 /// Call `next` for a file format iterator.
118 macro_rules
! next_inner
{
119 ($inner
:expr
, $from
:ident
, $to
:ident
) => {
121 #[cfg(feature = "coff")]
122 $from
::Coff(ref mut iter
) => iter
.next().map($to
::Coff
),
123 #[cfg(feature = "elf")]
124 $from
::Elf32(ref mut iter
) => iter
.next().map($to
::Elf32
),
125 #[cfg(feature = "elf")]
126 $from
::Elf64(ref mut iter
) => iter
.next().map($to
::Elf64
),
127 #[cfg(feature = "macho")]
128 $from
::MachO32(ref mut iter
) => iter
.next().map($to
::MachO32
),
129 #[cfg(feature = "macho")]
130 $from
::MachO64(ref mut iter
) => iter
.next().map($to
::MachO64
),
131 #[cfg(feature = "pe")]
132 $from
::Pe32(ref mut iter
) => iter
.next().map($to
::Pe32
),
133 #[cfg(feature = "pe")]
134 $from
::Pe64(ref mut iter
) => iter
.next().map($to
::Pe64
),
135 #[cfg(feature = "wasm")]
136 $from
::Wasm(ref mut iter
) => iter
.next().map($to
::Wasm
),
143 /// Most functionality is provided by the `Object` trait implementation.
145 pub struct File
<'data
> {
146 inner
: FileInternal
<'data
>,
149 #[allow(clippy::large_enum_variant)]
151 enum FileInternal
<'data
> {
152 #[cfg(feature = "coff")]
153 Coff(coff
::CoffFile
<'data
>),
154 #[cfg(feature = "elf")]
155 Elf32(elf
::ElfFile32
<'data
>),
156 #[cfg(feature = "elf")]
157 Elf64(elf
::ElfFile64
<'data
>),
158 #[cfg(feature = "macho")]
159 MachO32(macho
::MachOFile32
<'data
>),
160 #[cfg(feature = "macho")]
161 MachO64(macho
::MachOFile64
<'data
>),
162 #[cfg(feature = "pe")]
163 Pe32(pe
::PeFile32
<'data
>),
164 #[cfg(feature = "pe")]
165 Pe64(pe
::PeFile64
<'data
>),
166 #[cfg(feature = "wasm")]
167 Wasm(wasm
::WasmFile
<'data
>),
170 impl<'data
> File
<'data
> {
171 /// Parse the raw file data.
172 pub fn parse(data
: &'data
[u8]) -> Result
<Self> {
174 return Err(Error("File too short"));
177 let inner
= match [data
[0], data
[1], data
[2], data
[3], data
[4]] {
179 #[cfg(feature = "elf")]
180 [0x7f, b'E'
, b'L'
, b'F'
, 1] => FileInternal
::Elf32(elf
::ElfFile32
::parse(data
)?
),
182 #[cfg(feature = "elf")]
183 [0x7f, b'E'
, b'L'
, b'F'
, 2] => FileInternal
::Elf64(elf
::ElfFile64
::parse(data
)?
),
185 #[cfg(feature = "macho")]
186 [0xfe, 0xed, 0xfa, 0xce, _
]
187 | [0xce, 0xfa, 0xed, 0xfe, _
] => FileInternal
::MachO32(macho
::MachOFile32
::parse(data
)?
),
189 #[cfg(feature = "macho")]
190 | [0xfe, 0xed, 0xfa, 0xcf, _
]
191 | [0xcf, 0xfa, 0xed, 0xfe, _
] => FileInternal
::MachO64(macho
::MachOFile64
::parse(data
)?
),
193 #[cfg(feature = "wasm")]
194 [0x00, b'a'
, b's'
, b'm'
, _
] => FileInternal
::Wasm(wasm
::WasmFile
::parse(data
)?
),
195 // MS-DOS, assume stub for Windows PE32 or PE32+
196 #[cfg(feature = "pe")]
197 [b'M'
, b'Z'
, _
, _
, _
] => {
198 // `optional_header_magic` doesn't care if it's `PeFile32` and `PeFile64`.
199 match pe
::PeFile64
::optional_header_magic(data
) {
200 Ok(crate::pe
::IMAGE_NT_OPTIONAL_HDR32_MAGIC
) => {
201 FileInternal
::Pe32(pe
::PeFile32
::parse(data
)?
)
203 Ok(crate::pe
::IMAGE_NT_OPTIONAL_HDR64_MAGIC
) => {
204 FileInternal
::Pe64(pe
::PeFile64
::parse(data
)?
)
206 _
=> return Err(Error("Unknown MS-DOS file")),
209 // TODO: more COFF machines
210 #[cfg(feature = "coff")]
212 [0x4c, 0x01, _
, _
, _
]
214 | [0x64, 0x86, _
, _
, _
] => FileInternal
::Coff(coff
::CoffFile
::parse(data
)?
),
215 _
=> return Err(Error("Unknown file magic")),
220 /// Return the file format.
221 pub fn format(&self) -> BinaryFormat
{
223 #[cfg(feature = "coff")]
224 FileInternal
::Coff(_
) => BinaryFormat
::Coff
,
225 #[cfg(feature = "elf")]
226 FileInternal
::Elf32(_
) | FileInternal
::Elf64(_
) => BinaryFormat
::Elf
,
227 #[cfg(feature = "macho")]
228 FileInternal
::MachO32(_
) | FileInternal
::MachO64(_
) => BinaryFormat
::MachO
,
229 #[cfg(feature = "pe")]
230 FileInternal
::Pe32(_
) | FileInternal
::Pe64(_
) => BinaryFormat
::Pe
,
231 #[cfg(feature = "wasm")]
232 FileInternal
::Wasm(_
) => BinaryFormat
::Wasm
,
237 impl<'data
> read
::private
::Sealed
for File
<'data
> {}
239 impl<'data
, 'file
> Object
<'data
, 'file
> for File
<'data
>
243 type Segment
= Segment
<'data
, 'file
>;
244 type SegmentIterator
= SegmentIterator
<'data
, 'file
>;
245 type Section
= Section
<'data
, 'file
>;
246 type SectionIterator
= SectionIterator
<'data
, 'file
>;
247 type Comdat
= Comdat
<'data
, 'file
>;
248 type ComdatIterator
= ComdatIterator
<'data
, 'file
>;
249 type Symbol
= Symbol
<'data
, 'file
>;
250 type SymbolIterator
= SymbolIterator
<'data
, 'file
>;
251 type SymbolTable
= SymbolTable
<'data
, 'file
>;
253 fn architecture(&self) -> Architecture
{
254 with_inner
!(self.inner
, FileInternal
, |x
| x
.architecture())
257 fn is_little_endian(&self) -> bool
{
258 with_inner
!(self.inner
, FileInternal
, |x
| x
.is_little_endian())
261 fn is_64(&self) -> bool
{
262 with_inner
!(self.inner
, FileInternal
, |x
| x
.is_64())
265 fn segments(&'file
self) -> SegmentIterator
<'data
, 'file
> {
267 inner
: map_inner
!(self.inner
, FileInternal
, SegmentIteratorInternal
, |x
| x
272 fn section_by_name(&'file
self, section_name
: &str) -> Option
<Section
<'data
, 'file
>> {
273 map_inner_option
!(self.inner
, FileInternal
, SectionInternal
, |x
| x
274 .section_by_name(section_name
))
275 .map(|inner
| Section { inner }
)
278 fn section_by_index(&'file
self, index
: SectionIndex
) -> Result
<Section
<'data
, 'file
>> {
279 map_inner_option
!(self.inner
, FileInternal
, SectionInternal
, |x
| x
280 .section_by_index(index
))
281 .map(|inner
| Section { inner }
)
284 fn sections(&'file
self) -> SectionIterator
<'data
, 'file
> {
286 inner
: map_inner
!(self.inner
, FileInternal
, SectionIteratorInternal
, |x
| x
291 fn comdats(&'file
self) -> ComdatIterator
<'data
, 'file
> {
293 inner
: map_inner
!(self.inner
, FileInternal
, ComdatIteratorInternal
, |x
| x
298 fn symbol_by_index(&'file
self, index
: SymbolIndex
) -> Result
<Symbol
<'data
, 'file
>> {
299 map_inner_option
!(self.inner
, FileInternal
, SymbolInternal
, |x
| x
300 .symbol_by_index(index
))
301 .map(|inner
| Symbol { inner }
)
304 fn symbols(&'file
self) -> SymbolIterator
<'data
, 'file
> {
306 inner
: map_inner
!(self.inner
, FileInternal
, SymbolIteratorInternal
, |x
| x
311 fn symbol_table(&'file
self) -> Option
<SymbolTable
<'data
, 'file
>> {
312 map_inner_option
!(self.inner
, FileInternal
, SymbolTableInternal
, |x
| x
314 .map(|inner
| SymbolTable { inner }
)
317 fn dynamic_symbols(&'file
self) -> SymbolIterator
<'data
, 'file
> {
319 inner
: map_inner
!(self.inner
, FileInternal
, SymbolIteratorInternal
, |x
| x
324 fn dynamic_symbol_table(&'file
self) -> Option
<SymbolTable
<'data
, 'file
>> {
325 map_inner_option
!(self.inner
, FileInternal
, SymbolTableInternal
, |x
| x
326 .dynamic_symbol_table())
327 .map(|inner
| SymbolTable { inner }
)
330 fn symbol_map(&self) -> SymbolMap
<SymbolMapName
<'data
>> {
331 with_inner
!(self.inner
, FileInternal
, |x
| x
.symbol_map())
334 fn object_map(&self) -> ObjectMap
<'data
> {
335 with_inner
!(self.inner
, FileInternal
, |x
| x
.object_map())
338 fn has_debug_symbols(&self) -> bool
{
339 with_inner
!(self.inner
, FileInternal
, |x
| x
.has_debug_symbols())
343 fn mach_uuid(&self) -> Result
<Option
<[u8; 16]>> {
344 with_inner
!(self.inner
, FileInternal
, |x
| x
.mach_uuid())
348 fn build_id(&self) -> Result
<Option
<&'data
[u8]>> {
349 with_inner
!(self.inner
, FileInternal
, |x
| x
.build_id())
353 fn gnu_debuglink(&self) -> Result
<Option
<(&'data
[u8], u32)>> {
354 with_inner
!(self.inner
, FileInternal
, |x
| x
.gnu_debuglink())
357 fn entry(&self) -> u64 {
358 with_inner
!(self.inner
, FileInternal
, |x
| x
.entry())
361 fn flags(&self) -> FileFlags
{
362 with_inner
!(self.inner
, FileInternal
, |x
| x
.flags())
366 /// An iterator over the segments of a `File`.
368 pub struct SegmentIterator
<'data
, 'file
>
372 inner
: SegmentIteratorInternal
<'data
, 'file
>,
376 enum SegmentIteratorInternal
<'data
, 'file
>
380 #[cfg(feature = "coff")]
381 Coff(coff
::CoffSegmentIterator
<'data
, 'file
>),
382 #[cfg(feature = "elf")]
383 Elf32(elf
::ElfSegmentIterator32
<'data
, 'file
>),
384 #[cfg(feature = "elf")]
385 Elf64(elf
::ElfSegmentIterator64
<'data
, 'file
>),
386 #[cfg(feature = "macho")]
387 MachO32(macho
::MachOSegmentIterator32
<'data
, 'file
>),
388 #[cfg(feature = "macho")]
389 MachO64(macho
::MachOSegmentIterator64
<'data
, 'file
>),
390 #[cfg(feature = "pe")]
391 Pe32(pe
::PeSegmentIterator32
<'data
, 'file
>),
392 #[cfg(feature = "pe")]
393 Pe64(pe
::PeSegmentIterator64
<'data
, 'file
>),
394 #[cfg(feature = "wasm")]
395 Wasm(wasm
::WasmSegmentIterator
<'data
, 'file
>),
398 impl<'data
, 'file
> Iterator
for SegmentIterator
<'data
, 'file
> {
399 type Item
= Segment
<'data
, 'file
>;
401 fn next(&mut self) -> Option
<Self::Item
> {
402 next_inner
!(self.inner
, SegmentIteratorInternal
, SegmentInternal
)
403 .map(|inner
| Segment { inner }
)
407 /// A segment of a `File`.
408 pub struct Segment
<'data
, 'file
>
412 inner
: SegmentInternal
<'data
, 'file
>,
416 enum SegmentInternal
<'data
, 'file
>
420 #[cfg(feature = "coff")]
421 Coff(coff
::CoffSegment
<'data
, 'file
>),
422 #[cfg(feature = "elf")]
423 Elf32(elf
::ElfSegment32
<'data
, 'file
>),
424 #[cfg(feature = "elf")]
425 Elf64(elf
::ElfSegment64
<'data
, 'file
>),
426 #[cfg(feature = "macho")]
427 MachO32(macho
::MachOSegment32
<'data
, 'file
>),
428 #[cfg(feature = "macho")]
429 MachO64(macho
::MachOSegment64
<'data
, 'file
>),
430 #[cfg(feature = "pe")]
431 Pe32(pe
::PeSegment32
<'data
, 'file
>),
432 #[cfg(feature = "pe")]
433 Pe64(pe
::PeSegment64
<'data
, 'file
>),
434 #[cfg(feature = "wasm")]
435 Wasm(wasm
::WasmSegment
<'data
, 'file
>),
438 impl<'data
, 'file
> fmt
::Debug
for Segment
<'data
, 'file
> {
439 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
440 // It's painful to do much better than this
441 let mut s
= f
.debug_struct("Segment");
443 Ok(Some(ref name
)) => {
444 s
.field("name", name
);
448 s
.field("name", &"<invalid>");
451 s
.field("address", &self.address())
452 .field("size", &self.size())
457 impl<'data
, 'file
> read
::private
::Sealed
for Segment
<'data
, 'file
> {}
459 impl<'data
, 'file
> ObjectSegment
<'data
> for Segment
<'data
, 'file
> {
460 fn address(&self) -> u64 {
461 with_inner
!(self.inner
, SegmentInternal
, |x
| x
.address())
464 fn size(&self) -> u64 {
465 with_inner
!(self.inner
, SegmentInternal
, |x
| x
.size())
468 fn align(&self) -> u64 {
469 with_inner
!(self.inner
, SegmentInternal
, |x
| x
.align())
472 fn file_range(&self) -> (u64, u64) {
473 with_inner
!(self.inner
, SegmentInternal
, |x
| x
.file_range())
476 fn data(&self) -> Result
<&'data
[u8]> {
477 with_inner
!(self.inner
, SegmentInternal
, |x
| x
.data())
480 fn data_range(&self, address
: u64, size
: u64) -> Result
<Option
<&'data
[u8]>> {
481 with_inner
!(self.inner
, SegmentInternal
, |x
| x
.data_range(address
, size
))
484 fn name(&self) -> Result
<Option
<&str>> {
485 with_inner
!(self.inner
, SegmentInternal
, |x
| x
.name())
489 /// An iterator of the sections of a `File`.
491 pub struct SectionIterator
<'data
, 'file
>
495 inner
: SectionIteratorInternal
<'data
, 'file
>,
498 // we wrap our enums in a struct so that they are kept private.
500 enum SectionIteratorInternal
<'data
, 'file
>
504 #[cfg(feature = "coff")]
505 Coff(coff
::CoffSectionIterator
<'data
, 'file
>),
506 #[cfg(feature = "elf")]
507 Elf32(elf
::ElfSectionIterator32
<'data
, 'file
>),
508 #[cfg(feature = "elf")]
509 Elf64(elf
::ElfSectionIterator64
<'data
, 'file
>),
510 #[cfg(feature = "macho")]
511 MachO32(macho
::MachOSectionIterator32
<'data
, 'file
>),
512 #[cfg(feature = "macho")]
513 MachO64(macho
::MachOSectionIterator64
<'data
, 'file
>),
514 #[cfg(feature = "pe")]
515 Pe32(pe
::PeSectionIterator32
<'data
, 'file
>),
516 #[cfg(feature = "pe")]
517 Pe64(pe
::PeSectionIterator64
<'data
, 'file
>),
518 #[cfg(feature = "wasm")]
519 Wasm(wasm
::WasmSectionIterator
<'data
, 'file
>),
522 impl<'data
, 'file
> Iterator
for SectionIterator
<'data
, 'file
> {
523 type Item
= Section
<'data
, 'file
>;
525 fn next(&mut self) -> Option
<Self::Item
> {
526 next_inner
!(self.inner
, SectionIteratorInternal
, SectionInternal
)
527 .map(|inner
| Section { inner }
)
531 /// A Section of a File
532 pub struct Section
<'data
, 'file
>
536 inner
: SectionInternal
<'data
, 'file
>,
539 enum SectionInternal
<'data
, 'file
>
543 #[cfg(feature = "coff")]
544 Coff(coff
::CoffSection
<'data
, 'file
>),
545 #[cfg(feature = "elf")]
546 Elf32(elf
::ElfSection32
<'data
, 'file
>),
547 #[cfg(feature = "elf")]
548 Elf64(elf
::ElfSection64
<'data
, 'file
>),
549 #[cfg(feature = "macho")]
550 MachO32(macho
::MachOSection32
<'data
, 'file
>),
551 #[cfg(feature = "macho")]
552 MachO64(macho
::MachOSection64
<'data
, 'file
>),
553 #[cfg(feature = "pe")]
554 Pe32(pe
::PeSection32
<'data
, 'file
>),
555 #[cfg(feature = "pe")]
556 Pe64(pe
::PeSection64
<'data
, 'file
>),
557 #[cfg(feature = "wasm")]
558 Wasm(wasm
::WasmSection
<'data
, 'file
>),
561 impl<'data
, 'file
> fmt
::Debug
for Section
<'data
, 'file
> {
562 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
563 // It's painful to do much better than this
564 let mut s
= f
.debug_struct("Section");
565 match self.segment_name() {
566 Ok(Some(ref name
)) => {
567 s
.field("segment", name
);
571 s
.field("segment", &"<invalid>");
574 s
.field("name", &self.name().unwrap_or("<invalid>"))
575 .field("address", &self.address())
576 .field("size", &self.size())
577 .field("align", &self.align())
578 .field("kind", &self.kind())
579 .field("flags", &self.flags())
584 impl<'data
, 'file
> read
::private
::Sealed
for Section
<'data
, 'file
> {}
586 impl<'data
, 'file
> ObjectSection
<'data
> for Section
<'data
, 'file
> {
587 type RelocationIterator
= RelocationIterator
<'data
, 'file
>;
589 fn index(&self) -> SectionIndex
{
590 with_inner
!(self.inner
, SectionInternal
, |x
| x
.index())
593 fn address(&self) -> u64 {
594 with_inner
!(self.inner
, SectionInternal
, |x
| x
.address())
597 fn size(&self) -> u64 {
598 with_inner
!(self.inner
, SectionInternal
, |x
| x
.size())
601 fn align(&self) -> u64 {
602 with_inner
!(self.inner
, SectionInternal
, |x
| x
.align())
605 fn file_range(&self) -> Option
<(u64, u64)> {
606 with_inner
!(self.inner
, SectionInternal
, |x
| x
.file_range())
609 fn data(&self) -> Result
<&'data
[u8]> {
610 with_inner
!(self.inner
, SectionInternal
, |x
| x
.data())
613 fn data_range(&self, address
: u64, size
: u64) -> Result
<Option
<&'data
[u8]>> {
614 with_inner
!(self.inner
, SectionInternal
, |x
| x
.data_range(address
, size
))
617 fn compressed_data(&self) -> Result
<CompressedData
<'data
>> {
618 with_inner
!(self.inner
, SectionInternal
, |x
| x
.compressed_data())
621 fn name(&self) -> Result
<&str> {
622 with_inner
!(self.inner
, SectionInternal
, |x
| x
.name())
625 fn segment_name(&self) -> Result
<Option
<&str>> {
626 with_inner
!(self.inner
, SectionInternal
, |x
| x
.segment_name())
629 fn kind(&self) -> SectionKind
{
630 with_inner
!(self.inner
, SectionInternal
, |x
| x
.kind())
633 fn relocations(&self) -> RelocationIterator
<'data
, 'file
> {
638 RelocationIteratorInternal
,
644 fn flags(&self) -> SectionFlags
{
645 with_inner
!(self.inner
, SectionInternal
, |x
| x
.flags())
649 /// An iterator of the COMDAT section groups of a `File`.
651 pub struct ComdatIterator
<'data
, 'file
>
655 inner
: ComdatIteratorInternal
<'data
, 'file
>,
659 enum ComdatIteratorInternal
<'data
, 'file
>
663 #[cfg(feature = "coff")]
664 Coff(coff
::CoffComdatIterator
<'data
, 'file
>),
665 #[cfg(feature = "elf")]
666 Elf32(elf
::ElfComdatIterator32
<'data
, 'file
>),
667 #[cfg(feature = "elf")]
668 Elf64(elf
::ElfComdatIterator64
<'data
, 'file
>),
669 #[cfg(feature = "macho")]
670 MachO32(macho
::MachOComdatIterator32
<'data
, 'file
>),
671 #[cfg(feature = "macho")]
672 MachO64(macho
::MachOComdatIterator64
<'data
, 'file
>),
673 #[cfg(feature = "pe")]
674 Pe32(pe
::PeComdatIterator32
<'data
, 'file
>),
675 #[cfg(feature = "pe")]
676 Pe64(pe
::PeComdatIterator64
<'data
, 'file
>),
677 #[cfg(feature = "wasm")]
678 Wasm(wasm
::WasmComdatIterator
<'data
, 'file
>),
681 impl<'data
, 'file
> Iterator
for ComdatIterator
<'data
, 'file
> {
682 type Item
= Comdat
<'data
, 'file
>;
684 fn next(&mut self) -> Option
<Self::Item
> {
685 next_inner
!(self.inner
, ComdatIteratorInternal
, ComdatInternal
)
686 .map(|inner
| Comdat { inner }
)
690 /// A COMDAT section group of a `File`.
691 pub struct Comdat
<'data
, 'file
>
695 inner
: ComdatInternal
<'data
, 'file
>,
698 enum ComdatInternal
<'data
, 'file
>
702 #[cfg(feature = "coff")]
703 Coff(coff
::CoffComdat
<'data
, 'file
>),
704 #[cfg(feature = "elf")]
705 Elf32(elf
::ElfComdat32
<'data
, 'file
>),
706 #[cfg(feature = "elf")]
707 Elf64(elf
::ElfComdat64
<'data
, 'file
>),
708 #[cfg(feature = "macho")]
709 MachO32(macho
::MachOComdat32
<'data
, 'file
>),
710 #[cfg(feature = "macho")]
711 MachO64(macho
::MachOComdat64
<'data
, 'file
>),
712 #[cfg(feature = "pe")]
713 Pe32(pe
::PeComdat32
<'data
, 'file
>),
714 #[cfg(feature = "pe")]
715 Pe64(pe
::PeComdat64
<'data
, 'file
>),
716 #[cfg(feature = "wasm")]
717 Wasm(wasm
::WasmComdat
<'data
, 'file
>),
720 impl<'data
, 'file
> fmt
::Debug
for Comdat
<'data
, 'file
> {
721 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
722 let mut s
= f
.debug_struct("Comdat");
723 s
.field("symbol", &self.symbol())
724 .field("name", &self.name().unwrap_or("<invalid>"))
725 .field("kind", &self.kind())
730 impl<'data
, 'file
> read
::private
::Sealed
for Comdat
<'data
, 'file
> {}
732 impl<'data
, 'file
> ObjectComdat
<'data
> for Comdat
<'data
, 'file
> {
733 type SectionIterator
= ComdatSectionIterator
<'data
, 'file
>;
735 fn kind(&self) -> ComdatKind
{
736 with_inner
!(self.inner
, ComdatInternal
, |x
| x
.kind())
739 fn symbol(&self) -> SymbolIndex
{
740 with_inner
!(self.inner
, ComdatInternal
, |x
| x
.symbol())
743 fn name(&self) -> Result
<&str> {
744 with_inner
!(self.inner
, ComdatInternal
, |x
| x
.name())
747 fn sections(&self) -> ComdatSectionIterator
<'data
, 'file
> {
748 ComdatSectionIterator
{
752 ComdatSectionIteratorInternal
,
759 /// An iterator over COMDAT section entries.
761 pub struct ComdatSectionIterator
<'data
, 'file
>
765 inner
: ComdatSectionIteratorInternal
<'data
, 'file
>,
769 enum ComdatSectionIteratorInternal
<'data
, 'file
>
773 #[cfg(feature = "coff")]
774 Coff(coff
::CoffComdatSectionIterator
<'data
, 'file
>),
775 #[cfg(feature = "elf")]
776 Elf32(elf
::ElfComdatSectionIterator32
<'data
, 'file
>),
777 #[cfg(feature = "elf")]
778 Elf64(elf
::ElfComdatSectionIterator64
<'data
, 'file
>),
779 #[cfg(feature = "macho")]
780 MachO32(macho
::MachOComdatSectionIterator32
<'data
, 'file
>),
781 #[cfg(feature = "macho")]
782 MachO64(macho
::MachOComdatSectionIterator64
<'data
, 'file
>),
783 #[cfg(feature = "pe")]
784 Pe32(pe
::PeComdatSectionIterator32
<'data
, 'file
>),
785 #[cfg(feature = "pe")]
786 Pe64(pe
::PeComdatSectionIterator64
<'data
, 'file
>),
787 #[cfg(feature = "wasm")]
788 Wasm(wasm
::WasmComdatSectionIterator
<'data
, 'file
>),
791 impl<'data
, 'file
> Iterator
for ComdatSectionIterator
<'data
, 'file
> {
792 type Item
= SectionIndex
;
794 fn next(&mut self) -> Option
<Self::Item
> {
795 with_inner_mut
!(self.inner
, ComdatSectionIteratorInternal
, |x
| x
.next())
801 pub struct SymbolTable
<'data
, 'file
>
805 inner
: SymbolTableInternal
<'data
, 'file
>,
809 enum SymbolTableInternal
<'data
, 'file
>
813 #[cfg(feature = "coff")]
814 Coff(coff
::CoffSymbolTable
<'data
, 'file
>),
815 #[cfg(feature = "elf")]
816 Elf32(elf
::ElfSymbolTable32
<'data
, 'file
>),
817 #[cfg(feature = "elf")]
818 Elf64(elf
::ElfSymbolTable64
<'data
, 'file
>),
819 #[cfg(feature = "macho")]
820 MachO32(macho
::MachOSymbolTable32
<'data
, 'file
>),
821 #[cfg(feature = "macho")]
822 MachO64(macho
::MachOSymbolTable64
<'data
, 'file
>),
823 #[cfg(feature = "pe")]
824 Pe32(coff
::CoffSymbolTable
<'data
, 'file
>),
825 #[cfg(feature = "pe")]
826 Pe64(coff
::CoffSymbolTable
<'data
, 'file
>),
827 #[cfg(feature = "wasm")]
828 Wasm(wasm
::WasmSymbolTable
<'data
, 'file
>),
831 impl<'data
, 'file
> read
::private
::Sealed
for SymbolTable
<'data
, 'file
> {}
833 impl<'data
, 'file
> ObjectSymbolTable
<'data
> for SymbolTable
<'data
, 'file
> {
834 type Symbol
= Symbol
<'data
, 'file
>;
835 type SymbolIterator
= SymbolIterator
<'data
, 'file
>;
837 fn symbols(&self) -> Self::SymbolIterator
{
842 SymbolIteratorInternal
,
848 fn symbol_by_index(&self, index
: SymbolIndex
) -> Result
<Self::Symbol
> {
849 map_inner_option
!(self.inner
, SymbolTableInternal
, SymbolInternal
, |x
| x
850 .symbol_by_index(index
))
851 .map(|inner
| Symbol { inner }
)
855 /// An iterator over symbol table entries.
857 pub struct SymbolIterator
<'data
, 'file
>
861 inner
: SymbolIteratorInternal
<'data
, 'file
>,
865 enum SymbolIteratorInternal
<'data
, 'file
>
869 #[cfg(feature = "coff")]
870 Coff(coff
::CoffSymbolIterator
<'data
, 'file
>),
871 #[cfg(feature = "elf")]
872 Elf32(elf
::ElfSymbolIterator32
<'data
, 'file
>),
873 #[cfg(feature = "elf")]
874 Elf64(elf
::ElfSymbolIterator64
<'data
, 'file
>),
875 #[cfg(feature = "macho")]
876 MachO32(macho
::MachOSymbolIterator32
<'data
, 'file
>),
877 #[cfg(feature = "macho")]
878 MachO64(macho
::MachOSymbolIterator64
<'data
, 'file
>),
879 #[cfg(feature = "pe")]
880 Pe32(coff
::CoffSymbolIterator
<'data
, 'file
>),
881 #[cfg(feature = "pe")]
882 Pe64(coff
::CoffSymbolIterator
<'data
, 'file
>),
883 #[cfg(feature = "wasm")]
884 Wasm(wasm
::WasmSymbolIterator
<'data
, 'file
>),
887 impl<'data
, 'file
> Iterator
for SymbolIterator
<'data
, 'file
> {
888 type Item
= Symbol
<'data
, 'file
>;
890 fn next(&mut self) -> Option
<Self::Item
> {
891 next_inner
!(self.inner
, SymbolIteratorInternal
, SymbolInternal
)
892 .map(|inner
| Symbol { inner }
)
896 /// A symbol table entry.
897 pub struct Symbol
<'data
, 'file
>
901 inner
: SymbolInternal
<'data
, 'file
>,
904 enum SymbolInternal
<'data
, 'file
>
908 #[cfg(feature = "coff")]
909 Coff(coff
::CoffSymbol
<'data
, 'file
>),
910 #[cfg(feature = "elf")]
911 Elf32(elf
::ElfSymbol32
<'data
, 'file
>),
912 #[cfg(feature = "elf")]
913 Elf64(elf
::ElfSymbol64
<'data
, 'file
>),
914 #[cfg(feature = "macho")]
915 MachO32(macho
::MachOSymbol32
<'data
, 'file
>),
916 #[cfg(feature = "macho")]
917 MachO64(macho
::MachOSymbol64
<'data
, 'file
>),
918 #[cfg(feature = "pe")]
919 Pe32(coff
::CoffSymbol
<'data
, 'file
>),
920 #[cfg(feature = "pe")]
921 Pe64(coff
::CoffSymbol
<'data
, 'file
>),
922 #[cfg(feature = "wasm")]
923 Wasm(wasm
::WasmSymbol
<'data
, 'file
>),
926 impl<'data
, 'file
> fmt
::Debug
for Symbol
<'data
, 'file
> {
927 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
928 f
.debug_struct("Symbol")
929 .field("name", &self.name().unwrap_or("<invalid>"))
930 .field("address", &self.address())
931 .field("size", &self.size())
932 .field("kind", &self.kind())
933 .field("section", &self.section())
934 .field("scope", &self.scope())
935 .field("weak", &self.is_weak())
936 .field("flags", &self.flags())
941 impl<'data
, 'file
> read
::private
::Sealed
for Symbol
<'data
, 'file
> {}
943 impl<'data
, 'file
> ObjectSymbol
<'data
> for Symbol
<'data
, 'file
> {
944 fn index(&self) -> SymbolIndex
{
945 with_inner
!(self.inner
, SymbolInternal
, |x
| x
.index())
948 fn name(&self) -> Result
<&'data
str> {
949 with_inner
!(self.inner
, SymbolInternal
, |x
| x
.name())
952 fn address(&self) -> u64 {
953 with_inner
!(self.inner
, SymbolInternal
, |x
| x
.address())
956 fn size(&self) -> u64 {
957 with_inner
!(self.inner
, SymbolInternal
, |x
| x
.size())
960 fn kind(&self) -> SymbolKind
{
961 with_inner
!(self.inner
, SymbolInternal
, |x
| x
.kind())
964 fn section(&self) -> SymbolSection
{
965 with_inner
!(self.inner
, SymbolInternal
, |x
| x
.section())
968 fn is_undefined(&self) -> bool
{
969 with_inner
!(self.inner
, SymbolInternal
, |x
| x
.is_undefined())
972 fn is_definition(&self) -> bool
{
973 with_inner
!(self.inner
, SymbolInternal
, |x
| x
.is_definition())
976 fn is_common(&self) -> bool
{
977 with_inner
!(self.inner
, SymbolInternal
, |x
| x
.is_common())
980 fn is_weak(&self) -> bool
{
981 with_inner
!(self.inner
, SymbolInternal
, |x
| x
.is_weak())
984 fn scope(&self) -> SymbolScope
{
985 with_inner
!(self.inner
, SymbolInternal
, |x
| x
.scope())
988 fn is_global(&self) -> bool
{
989 with_inner
!(self.inner
, SymbolInternal
, |x
| x
.is_global())
992 fn is_local(&self) -> bool
{
993 with_inner
!(self.inner
, SymbolInternal
, |x
| x
.is_local())
996 fn flags(&self) -> SymbolFlags
<SectionIndex
> {
997 with_inner
!(self.inner
, SymbolInternal
, |x
| x
.flags())
1001 /// An iterator over relocation entries
1003 pub struct RelocationIterator
<'data
, 'file
>
1007 inner
: RelocationIteratorInternal
<'data
, 'file
>,
1011 enum RelocationIteratorInternal
<'data
, 'file
>
1015 #[cfg(feature = "coff")]
1016 Coff(coff
::CoffRelocationIterator
<'data
, 'file
>),
1017 #[cfg(feature = "elf")]
1018 Elf32(elf
::ElfRelocationIterator32
<'data
, 'file
>),
1019 #[cfg(feature = "elf")]
1020 Elf64(elf
::ElfRelocationIterator64
<'data
, 'file
>),
1021 #[cfg(feature = "macho")]
1022 MachO32(macho
::MachORelocationIterator32
<'data
, 'file
>),
1023 #[cfg(feature = "macho")]
1024 MachO64(macho
::MachORelocationIterator64
<'data
, 'file
>),
1025 #[cfg(feature = "pe")]
1026 Pe32(pe
::PeRelocationIterator
<'data
, 'file
>),
1027 #[cfg(feature = "pe")]
1028 Pe64(pe
::PeRelocationIterator
<'data
, 'file
>),
1029 #[cfg(feature = "wasm")]
1030 Wasm(wasm
::WasmRelocationIterator
<'data
, 'file
>),
1033 impl<'data
, 'file
> Iterator
for RelocationIterator
<'data
, 'file
> {
1034 type Item
= (u64, Relocation
);
1036 fn next(&mut self) -> Option
<Self::Item
> {
1037 with_inner_mut
!(self.inner
, RelocationIteratorInternal
, |x
| x
.next())