pijul nest
guest [sign in]

Elfedit: fixing an alignment issue on GCC

pmeunier
May 9, 2025, 3:49 PM
E6W7X7U3IC5542LG2KFLCFIVWZS4BSNT4KF7FRKCM6XVZTN3CNJAC

Dependencies

  • [2] VZTI2E23 Elfedit: handling the case where we move the same section we're adding
  • [3] 5PJAXSZ7 Elfedit: correct reallocation of dynstr/dynamic
  • [4] AR2X3TLA Initial commit: introducing elfedit
  • [5] VR4QJBTN Elfedit: file sizes not aligned with page boundaries
  • [*] WGAKJ25E Adding a debug_svg command

Change contents

  • edit in elfedit/src/lib.rs at line 575
    [7.1304]
    [7.1304]
    pub fn dynsym(&self) -> Dynsym {
    let header = self.header();
    let id = self.id();
    let names = self.names(id.data, &header).unwrap();
    for i in 0..header.shnum(id.data) {
    let s = self.section(i as usize).unwrap();
    let name = names.name(s.name(id.data) as usize).unwrap();
    if name.to_bytes() == b".dynsym" {
    let offset = s.offset(id.data) as usize;
    let size = s.size(id.data) as usize;
    if id.class == Bits::B32 {
    return Dynsym::B32(unsafe {
    std::slice::from_raw_parts(
    self.map.as_ptr().add(offset) as *const u8 as *const Elf32Sym,
    size / std::mem::size_of::<Elf32Sym>(),
    )
    })
    } else if id.class == Bits::B64 {
    return Dynsym::B64(unsafe {
    std::slice::from_raw_parts(
    self.map.as_ptr().add(offset) as *const u8 as *const Elf64Sym,
    size / std::mem::size_of::<Elf64Sym>(),
    )
    })
    }
    }
    }
    Dynsym::B64(&[])
    }
    pub fn verneed(&self) -> Vec<(Verneed, Vec<Vernaux>)> {
    let header = self.header();
    let id = self.id();
    let names = self.names(id.data, &header).unwrap();
    let mut result = Vec::new();
    for i in 0..header.shnum(id.data) {
    let s = self.section(i as usize).unwrap();
    let name = names.name(s.name(id.data) as usize).unwrap();
    if name.to_bytes() == b".gnu.version_r" {
    let offset = s.offset(id.data) as usize;
    let size = s.size(id.data) as usize;
    unsafe {
    let mut current = self.map.as_ptr().add(offset) as *const u8;
    loop {
    assert!((current as usize) < offset + size);
    let mut aux = Vec::new();
    let mut aux_ptr = current.add((&*(current as *const Verneed)).aux as usize) as *const u8;
    loop {
    assert!((aux_ptr as usize) < offset + size);
    aux.push(*(aux_ptr as *const Vernaux));
    let next = (&*(aux_ptr as *const Vernaux)).next as usize;
    if next == 0 {
    break
    }
    aux_ptr = aux_ptr.add(next);
    }
    result.push((*(current as *const Verneed), aux));
    let next = (&*(current as *const Vernaux)).next as usize;
    if next == 0 {
    break
    }
    current = current.add(next);
    }
    }
    }
    }
    result
    }
  • edit in elfedit/src/lib.rs at line 1312
    [3.25558][3.13672:13746]()
    last_vaddr = rounded_last_vaddr + rounded_moved as usize;
  • edit in elfedit/src/lib.rs at line 1328
    [3.25661]
    [3.14161]
    assert_eq!(new_offset % 4096, rounded_last_vaddr % 4096);
  • replacement in elfedit/src/lib.rs at line 1334
    [3.14300][3.14300:14351]()
    sec.set_addr(id, last_vaddr as usize);
    [3.14300]
    [2.379]
    sec.set_addr(id, rounded_last_vaddr as usize);
  • replacement in elfedit/src/lib.rs at line 1345
    [2.857][2.857:915]()
    p.set_vaddr(id, last_vaddr as usize);
    [2.857]
    [2.915]
    p.set_vaddr(id, rounded_last_vaddr as usize);
  • edit in elfedit/src/lib.rs at line 2043
    [3.42935]
    [3.42935]
    #[repr(C)]
  • edit in elfedit/src/lib.rs at line 2050
    [3.43041]
    [3.43041]
    #[repr(C)]
  • edit in elfedit/src/lib.rs at line 2056
    [3.43096]
    [3.43096]
    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
    #[repr(C)]
    pub struct Elf32Sym {
    name: Endian<u32>,
    value: Endian<u32>,
    size: Endian<u32>,
    info: u8,
    other: u8,
    shndx: Endian<u16>,
    }
    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
    #[repr(C)]
    pub struct Elf64Sym {
    name: Endian<u32>,
    info: u8,
    other: u8,
    shndx: Endian<u16>,
    value: Endian<u64>,
    size: Endian<u64>,
    }
    #[derive(Debug)]
    pub enum Dynsym<'a> {
    B32(&'a [Elf32Sym]),
    B64(&'a [Elf64Sym]),
    }
    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
    #[repr(C)]
    pub struct Verneed {
    version: u16,
    cnt: u16,
    file: u32,
    aux: u32,
    next: u32,
    }
    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
    #[repr(C)]
    pub struct Vernaux {
    hash: u32,
    flags: u16,
    other: u16,
    name: u32,
    next: u32,
    }