ms_codeview/syms/
builder.rs1use super::SymKind;
4use crate::encoder::Encoder;
5use crate::types::TypeIndex;
6use bstr::BStr;
7
8#[derive(Default)]
10pub struct SymBuilder {
11 pub buffer: Vec<u8>,
13}
14
15impl SymBuilder {
16 pub fn new() -> Self {
18 Self { buffer: Vec::new() }
19 }
20
21 pub fn finish(self) -> Vec<u8> {
23 self.buffer
24 }
25
26 pub fn record(&mut self, kind: SymKind) -> RecordBuilder<'_> {
28 let record_start = self.buffer.len();
29 self.buffer.extend_from_slice(&[0, 0]); self.buffer.extend_from_slice(&kind.0.to_le_bytes());
31 RecordBuilder {
32 enc: Encoder::new(&mut self.buffer),
33 record_start,
34 }
35 }
36
37 pub fn udt(&mut self, ty: TypeIndex, name: &BStr) {
39 let mut r = self.record(SymKind::S_UDT);
40 r.enc.u32(ty.0);
41 r.enc.strz(name);
42 }
43
44 pub fn pub32(&mut self, flags: u32, offset: u32, segment: u16, name: &str) {
46 let mut r = self.record(SymKind::S_PUB32);
47 r.enc.u32(flags);
48 r.enc.u32(offset);
49 r.enc.u16(segment);
50 r.enc.strz(name.into());
51 }
52}
53
54pub struct RecordBuilder<'a> {
56 pub enc: Encoder<'a>,
58 record_start: usize,
61}
62
63impl<'a> Drop for RecordBuilder<'a> {
64 fn drop(&mut self) {
65 match self.enc.buf.len() & 3 {
67 1 => self.enc.buf.push(0xf1),
68 2 => self.enc.buf.extend_from_slice(&[0xf1, 0xf2]),
69 3 => self.enc.buf.extend_from_slice(&[0xf1, 0xf2, 0xf3]),
70 _ => {}
71 }
72
73 let record_len = self.enc.buf.len() - self.record_start - 2;
74 let record_field = &mut self.enc.buf[self.record_start..];
75 record_field[0] = record_len as u8;
76 record_field[1] = (record_len >> 8) as u8;
77 }
78}