pijul nest
guest [sign in]

Adding a debug_svg command

pmeunier
Apr 1, 2025, 6:25 AM
WGAKJ25EPI5BGHJN55GNLA3AOCZWSTF3D5SX5N4EVWTWPSV6SBFAC

Dependencies

  • [2] AR2X3TLA Initial commit: introducing elfedit

Change contents

  • edit in elfedit/src/lib.rs at line 278
    [2.7281]
    [2.7281]
    enum ProgramHeaderBits<'a> {
    B32(&'a ProgramHeader<u32>),
    B64(&'a ProgramHeader<u64>),
    }
    #[derive(Debug)]
  • edit in elfedit/src/lib.rs at line 327
    [2.8987]
    [2.8987]
    }
    }
    }
    impl<'a> ProgramHeaderBits<'a> {
    fn offset(&self, h: Endianness) -> u64 {
    match self {
    ProgramHeaderBits::B32(s) => EndianT::endian(s.offset, h) as u64,
    ProgramHeaderBits::B64(s) => EndianT::endian(s.offset, h),
    }
    }
    fn filesz(&self, h: Endianness) -> u64 {
    match self {
    ProgramHeaderBits::B32(s) => EndianT::endian(s.filesz, h) as u64,
    ProgramHeaderBits::B64(s) => EndianT::endian(s.filesz, h),
    }
    }
    fn flags(&self, h: Endianness) -> u32 {
    match self {
    ProgramHeaderBits::B32(s) => EndianT::endian(s.flags32, h),
    ProgramHeaderBits::B64(s) => EndianT::endian(s.flags64, h),
  • edit in elfedit/src/lib.rs at line 350
    [2.9003]
    [2.9003]
    fn vaddr(&self, h: Endianness) -> u64 {
    match self {
    ProgramHeaderBits::B32(s) => EndianT::endian(s.vaddr, h) as u64,
    ProgramHeaderBits::B64(s) => EndianT::endian(s.vaddr, h),
    }
    }
    fn memsz(&self, h: Endianness) -> u64 {
    match self {
    ProgramHeaderBits::B32(s) => EndianT::endian(s.memsz, h) as u64,
    ProgramHeaderBits::B64(s) => EndianT::endian(s.memsz, h),
    }
    }
  • edit in elfedit/src/lib.rs at line 450
    [2.11558]
    [2.11558]
    }
    pub fn debug_svg(&self) -> String {
    use std::fmt::Write;
    let mut svg = String::new();
    let mut x = 0;
    writeln!(
    svg,
    r#"<rect x="0" y="0" width="{}" height="10" fill="none" stroke="black" /><text text-anchor="middle" x="{}" y="10">File id</text>"#,
    std::mem::size_of::<Id>(),
    std::mem::size_of::<Id>()/2
    )
    .unwrap();
    x += std::mem::size_of::<Id>();
    let id = self.id();
    let header_w = if let Bits::B64 = id.class {
    std::mem::size_of::<Header<u64>>()
    } else {
    std::mem::size_of::<Header<u32>>()
    };
    writeln!(
    svg,
    r#"<rect x="{x}" y="0" width="{}" height="10" fill="none" stroke="black" /><text text-anchor="middle" x="{}" y="10">File header</text>"#,
    header_w,
    x + header_w / 2,
    )
    .unwrap();
    x += header_w;
    let h = self.header();
    let shoff = h.shoff(id.data);
    let shw = h.shnum(id.data) * h.shentsize(id.data);
    writeln!(
    svg,
    r#"<rect x="{shoff}" y="0" width="{shw}" height="10" fill="none" stroke="black" /><text text-anchor="middle" x="{}" y="10">Section headers</text>"#,
    shoff as usize + shw as usize/2,
    )
    .unwrap();
    x = x.max(shoff as usize + shw as usize);
    let phoff = h.phoff(id.data);
    let phw = h.phnum(id.data) * h.phentsize(id.data);
    writeln!(
    svg,
    r#"<rect x="{phoff}" y="0" width="{phw}" height="10" fill="none" stroke="black" /><text text-anchor="middle" x="{}" y="10">Program headers</text>"#,
    phoff as usize + phw as usize/2,
    )
    .unwrap();
    x = x.max(phoff as usize + phw as usize);
    let mut y = 10;
    for i in 0..h.shnum(id.data) {
    let s = self.section(i as usize);
    let off = s.offset(id.data);
    let sz = s.size(id.data);
    let names = self.names(id.data, &h);
    let name = names.name(s.name(id.data) as usize).unwrap();
    let xoff = off + sz / 2;
    writeln!(
    svg,
    r#"<rect x="{off}" y="{y}" width="{sz}" height="10" fill="none" stroke="blue" /><text text-anchor="middle" x="{xoff}" y="{y}" transform="rotate(90, {}, {y})">s{}: {}</text>"#,
    xoff,
    i,
    name.to_str().unwrap()
    )
    .unwrap();
    y += 10;
    }
    for i in 0..h.phnum(id.data) {
    let s = self.program(i as usize);
    let off = s.offset(id.data);
    let sz = s.filesz(id.data);
    let xoff = off + sz / 2;
    writeln!(
    svg,
    r#"<rect x="{off}" y="{y}" width="{sz}" height="10" fill="none" stroke="red" /><text text-anchor="middle" x="{xoff}" y="{}">p{}: {}</text>"#,
    y+10,
    i,
    s.flags(id.data)
    )
    .unwrap();
    y += 10;
    }
    for i in 0..h.phnum(id.data) {
    let s = self.program(i as usize);
    let off = s.vaddr(id.data);
    let sz = s.memsz(id.data);
    let xoff = off + sz / 2;
    x = x.max(off as usize + sz as usize);
    writeln!(
    svg,
    r#"<rect x="{off}" y="{y}" width="{sz}" height="10" fill="none" stroke="green" /><text text-anchor="middle" x="{xoff}" y="{}">p{}: {}</text>"#,
    y+10,
    i,
    s.flags(id.data),
    )
    .unwrap();
    y += 10;
    }
    let mut p = 4096;
    let yy = y + 50;
    let mut pages = String::new();
    while p < x {
    writeln!(
    pages,
    r#"<path d="M {p} -40 V {}" stroke="gray" stroke-dasharray="4" /><text text-anchor="middle" x="{p}" y="0">{p}</text>"#,
    y + 10,
    )
    .unwrap();
    p += 4096;
    }
    format!(
    r#"<svg viewBox="0 -40 {x} {yy}" xmlns="http://www.w3.org/2000/svg">{pages}{svg}</svg>"#,
    )
  • edit in elfedit/src/lib.rs at line 617
    [2.13307]
    [2.13307]
    fn program<'a>(&'a self, n: usize) -> ProgramHeaderBits<'a> {
    let h = self.header();
    let id = self.id().data;
    assert!(n < h.phnum(id) as usize);
    let ph = h.phoff(id) as usize + n * h.phentsize(id) as usize;
    match h {
    Header_::B32(_) => {
    assert!(ph + std::mem::size_of::<ProgramHeader<u32>>() <= self.map.len());
    assert_eq!(ph % std::mem::align_of::<ProgramHeader<u32>>(), 0);
    ProgramHeaderBits::B32(unsafe {
    &*((self.map.as_ptr()).add(ph) as *const u8 as *const ProgramHeader<u32>)
    })
    }
    Header_::B64(_) => {
    assert!(ph + std::mem::size_of::<ProgramHeader<u64>>() <= self.map.len());
    assert_eq!(ph % std::mem::align_of::<ProgramHeader<u32>>(), 0);
    ProgramHeaderBits::B64(unsafe {
    &*((self.map.as_ptr()).add(ph) as *const u8 as *const ProgramHeader<u64>)
    })
    }
    }
    }
  • replacement in elfedit/src/lib.rs at line 793
    [2.19626][2.19626:19863]()
    std::slice::from_raw_parts(
    self.map.as_ptr().add(offset) as *const u8 as *const Elf32Dyn,
    size / std::mem::size_of::<Elf32Dyn>(),
    )
    [2.19626]
    [2.19863]
    std::slice::from_raw_parts(
    self.map.as_ptr().add(offset) as *const u8 as *const Elf32Dyn,
    size / std::mem::size_of::<Elf32Dyn>(),
    )
  • replacement in elfedit/src/lib.rs at line 798
    [2.19890][2.19890:19969]()
    },
    Bits::B64 => {Dynamic::B64(unsafe {
    [2.19890]
    [2.19969]
    }
    Bits::B64 => Dynamic::B64(unsafe {
  • replacement in elfedit/src/lib.rs at line 806
    [2.20354][2.20354:20400]()
    })
    },
    [2.20354]
    [2.20400]
    }),