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