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