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