Name Description Size
compression_header.rs 9207
constants_header.rs 15902
constants_relocation.rs 58259
dynamic.rs Reverse order! 31242
gnu_hash.rs A Gnu Hash table as 4 sections: 1. Header 2. Bloom Filter 3. Hash Buckets 4. Chains The header has is an array of four `u32`s: 1. nbuckets 2. symndx 3. maskwords 4. shift2 See more: * <http://www.linker-aliens.org/blogs/ali/entry/gnu_hash_elf_sections> or <https://blogs.oracle.com/solaris/gnu-hash-elf-sections-v2> * <https://flapenguin.me/2017/05/10/elf-lookup-dt-gnu-hash/> 9066
header.rs 24372
mod.rs The generic ELF module, which gives access to ELF constants and other helper functions, which are independent of ELF bithood. Also defines an `Elf` struct which implements a unified parser that returns a wrapped `Elf64` or `Elf32` binary. To access the exact 32-bit or 64-bit versions, use [goblin::elf32::Header](header/header32/struct.Header.html)/[goblin::elf64::Header](header/header64/struct.Header.html), etc., for the various 32/64-bit structs. # Example ```rust use std::fs::File; pub fn read (bytes: &[u8]) { match goblin::elf::Elf::parse(&bytes) { Ok(binary) => { let entry = binary.entry; for ph in binary.program_headers { if ph.p_type == goblin::elf::program_header::PT_LOAD { // TODO: you should validate p_filesz before allocating. let mut _buf = vec![0u8; ph.p_filesz as usize]; // read responsibly } } }, Err(_) => () } } ``` This will properly access the underlying 32-bit or 64-bit binary automatically. Note that since 32-bit binaries typically have shorter 32-bit values in some cases (specifically for addresses and pointer values), these values are upcasted to u64/i64s when appropriate. See [goblin::elf::Elf](struct.Elf.html) for more information. You are still free to use the specific 32-bit or 64-bit versions by accessing them through `goblin::elf64`, etc., but you will have to parse and/or construct the various components yourself. In other words, there is no unified 32/64-bit `Elf` struct. # Note To use the automagic ELF datatype union parser, you _must_ enable/opt-in to the `elf64`, `elf32`, and `endian_fd` features if you disable `default`. 23443
note.rs 11073
program_header.rs Legal values for p_type (segment type). 14799
reloc.rs # Relocation computations The following notation is used to describe relocation computations specific to x86_64 ELF. * A: The addend used to compute the value of the relocatable field. * B: The base address at which a shared object is loaded into memory during execution. Generally, a shared object file is built with a base virtual address of 0. However, the execution address of the shared object is different. * G: The offset into the global offset table at which the address of the relocation entry's symbol resides during execution. * GOT: The address of the global offset table. * L: The section offset or address of the procedure linkage table entry for a symbol. * P: The section offset or address of the storage unit being relocated, computed using r_offset. * S: The value of the symbol whose index resides in the relocation entry. * Z: The size of the symbol whose index resides in the relocation entry. Below are some common x86_64 relocation computations you might find useful: | Relocation | Value | Size | Formula | |:--------------------------|:------|:----------|:------------------| | `R_X86_64_NONE` | 0 | NONE | NONE | | `R_X86_64_64` | 1 | 64 | S + A | | `R_X86_64_PC32` | 2 | 32 | S + A - P | | `R_X86_64_GOT32` | 3 | 32 | G + A | | `R_X86_64_PLT32` | 4 | 32 | L + A - P | | `R_X86_64_COPY` | 5 | NONE | NONE | | `R_X86_64_GLOB_DAT` | 6 | 64 | S | | `R_X86_64_JUMP_SLOT` | 7 | 64 | S | | `R_X86_64_RELATIVE` | 8 | 64 | B + A | | `R_X86_64_GOTPCREL` | 9 | 32 | G + GOT + A - P | | `R_X86_64_32` | 10 | 32 | S + A | | `R_X86_64_32S` | 11 | 32 | S + A | | `R_X86_64_16` | 12 | 16 | S + A | | `R_X86_64_PC16` | 13 | 16 | S + A - P | | `R_X86_64_8` | 14 | 8 | S + A | | `R_X86_64_PC8` | 15 | 8 | S + A - P | | `R_X86_64_DTPMOD64` | 16 | 64 | | | `R_X86_64_DTPOFF64` | 17 | 64 | | | `R_X86_64_TPOFF64` | 18 | 64 | | | `R_X86_64_TLSGD` | 19 | 32 | | | `R_X86_64_TLSLD` | 20 | 32 | | | `R_X86_64_DTPOFF32` | 21 | 32 | | | `R_X86_64_GOTTPOFF` | 22 | 32 | | | `R_X86_64_TPOFF32` | 23 | 32 | | | `R_X86_64_PC64` | 24 | 64 | S + A - P | | `R_X86_64_GOTOFF64` | 25 | 64 | S + A - GOT | | `R_X86_64_GOTPC32` | 26 | 32 | GOT + A - P | | `R_X86_64_SIZE32` | 32 | 32 | Z + A | | `R_X86_64_SIZE64` | 33 | 64 | Z + A | | `R_X86_64_GOTPC32_TLSDESC`| 34 | 32 | | | `R_X86_64_TLSDESC_CALL` | 35 | NONE | | | `R_X86_64_TLSDESC` | 36 | 64 × 2 | | | `R_X86_64_IRELATIVE` | 37 | 64 | indirect (B + A) | TLS information is at <http://people.redhat.com/aoliva/writeups/TLS/RFC-TLSDESC-x86.txt> `R_X86_64_IRELATIVE` is similar to `R_X86_64_RELATIVE` except that the value used in this relocation is the program address returned by the function, which takes no arguments, at the address of the result of the corresponding `R_X86_64_RELATIVE` relocation. Read more <https://docs.oracle.com/cd/E23824_01/html/819-0690/chapter6-54839.html> 19379
section_header.rs 21568
sym.rs 18574
symver.rs Symbol versioning Implementation of the GNU symbol versioning extension according to [LSB Core Specification - Symbol Versioning][lsb-symver]. # Examples List the dependencies of an ELF file that have [version needed][lsb-verneed] information along with the versions needed for each dependency. ```rust use goblin::error::Error; pub fn show_verneed(bytes: &[u8]) -> Result<(), Error> { let binary = goblin::elf::Elf::parse(&bytes)?; if let Some(verneed) = binary.verneed { for need_file in verneed.iter() { println!( "Depend on {:?} with version(s):", binary.dynstrtab.get_at(need_file.vn_file) ); for need_ver in need_file.iter() { println!("{:?}", binary.dynstrtab.get_at(need_ver.vna_name)); } } } Ok(()) } ``` List the [version defined][lsb-verdef] information of an ELF file, effectively listing the version defined by this ELF file. ```rust use goblin::error::Error; pub fn show_verdef(bytes: &[u8]) -> Result<(), Error> { let binary = goblin::elf::Elf::parse(&bytes)?; if let Some(verdef) = &binary.verdef { for def in verdef.iter() { for (n, aux) in def.iter().enumerate() { let name = binary.dynstrtab.get_at(aux.vda_name); match n { 0 => print!("Name: {:?}", name), 1 => print!(" Parent: {:?}", name), _ => print!(", {:?}", name), } } print!("\n"); } } Ok(()) } ``` [lsb-symver]: https://refspecs.linuxbase.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/symversion.html [lsb-verneed]: https://refspecs.linuxbase.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/symversion.html#SYMVERRQMTS [lsb-verdef]: https://refspecs.linuxbase.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/symversion.html#SYMVERDEFS 25897