Skip to content

Commit

Permalink
elf: gnu symbol versioning (#280)
Browse files Browse the repository at this point in the history
* elf.dynamic: Parse DT_VERDEF + DT_VERDEFNUM dynamic tags into DynamicInfo struct
* elf.symver: add struct definitions and reading part for .gnu.version_r (SHT_GNU_verdef) section
* elf.symver: add tests for parsing .gnu.version_r section
* elf.symver: make structs used by user more ergonomic by using usize

Implement some std traits:
    - IntoIter
    - ExactSizeIterator
    - FusedIterator

* elf.symver: add struct definitions and reading part for .gnu.version_d (SHT_GNU_verdef) section + doc example
* elf.symver: Use sub-module as feature guard

Use sub-module rather than macro to implement feature guard, as
`cargo fmt` doesn't seem to see through the macro based approach.

* add tests for parsing .gnu.version_d section
* elf.symver: add struct definitions and reading part for .gnu.version (SHT_GNU_versym) section
* elf.symver: add tests for parsing .gnu.version section
* elf.symver: added some convenience methods to Verdef
- Return 0 as lower bound in size_hint impls (better hint for corrupt
  ELFs)
- Verdef/Verdaux/Verneed/Vernaux Iterator: Start yielding None on the
  next call if there is no valid next index
  • Loading branch information
johannst committed Sep 14, 2021
1 parent cd22783 commit 73b5e27
Show file tree
Hide file tree
Showing 12 changed files with 1,272 additions and 2 deletions.
6 changes: 6 additions & 0 deletions src/elf/dynamic.rs
Expand Up @@ -614,6 +614,8 @@ macro_rules! elf_dynamic_info_std_impl {
pub pltrelsz: usize,
pub pltrel: $size,
pub jmprel: usize,
pub verdef: $size,
pub verdefnum: $size,
pub verneed: $size,
pub verneednum: $size,
pub versym: $size,
Expand Down Expand Up @@ -658,6 +660,8 @@ macro_rules! elf_dynamic_info_std_impl {
DT_JMPREL => {
self.jmprel = vm_to_offset(phdrs, dynamic.d_val).unwrap_or(0) as usize
} // .rela.plt
DT_VERDEF => self.verdef = vm_to_offset(phdrs, dynamic.d_val).unwrap_or(0),
DT_VERDEFNUM => self.verdefnum = vm_to_offset(phdrs, dynamic.d_val).unwrap_or(0),
DT_VERNEED => self.verneed = vm_to_offset(phdrs, dynamic.d_val).unwrap_or(0),
DT_VERNEEDNUM => self.verneednum = dynamic.d_val as _,
DT_VERSYM => self.versym = vm_to_offset(phdrs, dynamic.d_val).unwrap_or(0),
Expand Down Expand Up @@ -750,6 +754,8 @@ macro_rules! elf_dynamic_info_std_impl {
.field("pltrelsz", &self.pltrelsz)
.field("pltrel", &self.pltrel)
.field("jmprel", &format_args!("0x{:x}", self.jmprel))
.field("verdef", &format_args!("0x{:x}", self.verdef))
.field("verdefnum", &self.verdefnum)
.field("verneed", &format_args!("0x{:x}", self.verneed))
.field("verneednum", &self.verneednum)
.field("versym", &format_args!("0x{:x}", self.versym))
Expand Down
22 changes: 22 additions & 0 deletions src/elf/mod.rs
Expand Up @@ -53,6 +53,8 @@ pub mod dynamic;
#[macro_use]
pub mod reloc;
pub mod note;
#[cfg(all(any(feature = "elf32", feature = "elf64"), feature = "alloc"))]
pub mod symver;

macro_rules! if_sylvan {
($($i:item)*) => ($(
Expand All @@ -78,6 +80,7 @@ if_sylvan! {
pub use dynamic::Dynamic;
pub use reloc::Reloc;
pub use reloc::RelocSection;
pub use symver::{VersymSection, VerdefSection, VerneedSection};

pub type ProgramHeaders = Vec<ProgramHeader>;
pub type SectionHeaders = Vec<SectionHeader>;
Expand Down Expand Up @@ -130,6 +133,15 @@ if_sylvan! {
pub entry: u64,
/// Whether the binary is little endian or not
pub little_endian: bool,
/// Contains the symbol version information from the optional section
/// [`SHT_GNU_VERSYM`][section_header::SHT_GNU_VERSYM] (GNU extenstion).
pub versym : Option<VersymSection<'a>>,
/// Contains the version definition information from the optional section
/// [`SHT_GNU_VERDEF`][section_header::SHT_GNU_VERDEF] (GNU extenstion).
pub verdef : Option<VerdefSection<'a>>,
/// Contains the version needed information from the optional section
/// [`SHT_GNU_VERNEED`][section_header::SHT_GNU_VERNEED] (GNU extenstion).
pub verneed : Option<VerneedSection<'a>>,
ctx: Ctx,
}

Expand Down Expand Up @@ -232,6 +244,9 @@ if_sylvan! {
entry: misc.entry,
little_endian: misc.little_endian,
ctx: misc.ctx,
versym: None,
verdef: None,
verneed: None,
})
}

Expand Down Expand Up @@ -334,6 +349,10 @@ if_sylvan! {
}
}

let versym = symver::VersymSection::parse(bytes, &section_headers, ctx)?;
let verdef = symver::VerdefSection::parse(bytes, &section_headers, ctx)?;
let verneed = symver::VerneedSection::parse(bytes, &section_headers, ctx)?;

Ok(Elf {
header,
program_headers,
Expand All @@ -356,6 +375,9 @@ if_sylvan! {
entry: misc.entry,
little_endian: misc.little_endian,
ctx: ctx,
versym,
verdef,
verneed,
})
}
}
Expand Down

0 comments on commit 73b5e27

Please sign in to comment.