}
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>"#,
)