Coverage Report

Created: 2026-03-26 07:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/gimli-0.33.0/src/write/writer.rs
Line
Count
Source
1
use crate::common::{Format, SectionId};
2
use crate::constants;
3
use crate::endianity::Endianity;
4
use crate::leb128::write::Leb128;
5
use crate::write::{Address, Error, Result};
6
7
/// A trait for writing the data to a DWARF section.
8
///
9
/// All write operations append to the section unless otherwise specified.
10
#[allow(clippy::len_without_is_empty)]
11
pub trait Writer {
12
    /// The endianity of bytes that are written.
13
    type Endian: Endianity;
14
15
    /// Return the endianity of bytes that are written.
16
    fn endian(&self) -> Self::Endian;
17
18
    /// Return the current section length.
19
    ///
20
    /// This may be used as an offset for future `write_at` calls.
21
    fn len(&self) -> usize;
22
23
    /// Write a slice.
24
    fn write(&mut self, bytes: &[u8]) -> Result<()>;
25
26
    /// Write a slice at a given offset.
27
    ///
28
    /// The write must not extend past the current section length.
29
    fn write_at(&mut self, offset: usize, bytes: &[u8]) -> Result<()>;
30
31
    /// Write an address.
32
    ///
33
    /// If the writer supports relocations, then it must provide its own implementation
34
    /// of this method.
35
    // TODO: use write_reference instead?
36
0
    fn write_address(&mut self, address: Address, size: u8) -> Result<()> {
37
0
        match address {
38
0
            Address::Constant(val) => self.write_udata(val, size),
39
0
            Address::Symbol { .. } => Err(Error::InvalidAddress),
40
        }
41
0
    }
42
43
    /// Write an address with a `.eh_frame` pointer encoding.
44
    ///
45
    /// The given size is only used for `DW_EH_PE_absptr` formats.
46
    ///
47
    /// If the writer supports relocations, then it must provide its own implementation
48
    /// of this method.
49
0
    fn write_eh_pointer(
50
0
        &mut self,
51
0
        address: Address,
52
0
        eh_pe: constants::DwEhPe,
53
0
        size: u8,
54
0
    ) -> Result<()> {
55
0
        match address {
56
0
            Address::Constant(val) => {
57
                // Indirect doesn't matter here.
58
0
                let val = match eh_pe.application() {
59
0
                    constants::DW_EH_PE_absptr => val,
60
                    constants::DW_EH_PE_pcrel => {
61
                        // TODO: better handling of sign
62
0
                        let offset = self.len() as u64;
63
0
                        val.wrapping_sub(offset)
64
                    }
65
                    _ => {
66
0
                        return Err(Error::UnsupportedPointerEncoding(eh_pe));
67
                    }
68
                };
69
0
                self.write_eh_pointer_data(val, eh_pe.format(), size)
70
            }
71
0
            Address::Symbol { .. } => Err(Error::InvalidAddress),
72
        }
73
0
    }
Unexecuted instantiation: <gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_eh_pointer
Unexecuted instantiation: <_ as gimli::write::writer::Writer>::write_eh_pointer
Unexecuted instantiation: <wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_eh_pointer
Unexecuted instantiation: <gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_eh_pointer
Unexecuted instantiation: <wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_eh_pointer
74
75
    /// Write a value with a `.eh_frame` pointer format.
76
    ///
77
    /// The given size is only used for `DW_EH_PE_absptr` formats.
78
    ///
79
    /// This must not be used directly for values that may require relocation.
80
0
    fn write_eh_pointer_data(
81
0
        &mut self,
82
0
        val: u64,
83
0
        format: constants::DwEhPe,
84
0
        size: u8,
85
0
    ) -> Result<()> {
86
0
        match format {
87
0
            constants::DW_EH_PE_absptr => self.write_udata(val, size),
88
0
            constants::DW_EH_PE_uleb128 => self.write_uleb128(val),
89
0
            constants::DW_EH_PE_udata2 => self.write_udata(val, 2),
90
0
            constants::DW_EH_PE_udata4 => self.write_udata(val, 4),
91
0
            constants::DW_EH_PE_udata8 => self.write_udata(val, 8),
92
0
            constants::DW_EH_PE_sleb128 => self.write_sleb128(val as i64),
93
0
            constants::DW_EH_PE_sdata2 => self.write_sdata(val as i64, 2),
94
0
            constants::DW_EH_PE_sdata4 => self.write_sdata(val as i64, 4),
95
0
            constants::DW_EH_PE_sdata8 => self.write_sdata(val as i64, 8),
96
0
            _ => Err(Error::UnsupportedPointerEncoding(format)),
97
        }
98
0
    }
Unexecuted instantiation: <gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_eh_pointer_data
Unexecuted instantiation: <wasmer_compiler_cranelift::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_eh_pointer_data
Unexecuted instantiation: <_ as gimli::write::writer::Writer>::write_eh_pointer_data
Unexecuted instantiation: <wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_eh_pointer_data
Unexecuted instantiation: <gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_eh_pointer_data
Unexecuted instantiation: <wasmer_compiler_cranelift::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_eh_pointer_data
Unexecuted instantiation: <wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_eh_pointer_data
99
100
    /// Write an offset that is relative to the start of the given section.
101
    ///
102
    /// If the writer supports relocations, then it must provide its own implementation
103
    /// of this method.
104
0
    fn write_offset(&mut self, val: usize, _section: SectionId, size: u8) -> Result<()> {
105
0
        self.write_udata(val as u64, size)
106
0
    }
107
108
    /// Write an offset that is relative to the start of the given section.
109
    ///
110
    /// If the writer supports relocations, then it must provide its own implementation
111
    /// of this method.
112
0
    fn write_offset_at(
113
0
        &mut self,
114
0
        offset: usize,
115
0
        val: usize,
116
0
        _section: SectionId,
117
0
        size: u8,
118
0
    ) -> Result<()> {
119
0
        self.write_udata_at(offset, val as u64, size)
120
0
    }
121
122
    /// Write a reference to a symbol.
123
    ///
124
    /// If the writer supports symbols, then it must provide its own implementation
125
    /// of this method.
126
0
    fn write_reference(&mut self, _symbol: usize, _size: u8) -> Result<()> {
127
0
        Err(Error::InvalidReference)
128
0
    }
Unexecuted instantiation: <wasmer_compiler_cranelift::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_reference
Unexecuted instantiation: <_ as gimli::write::writer::Writer>::write_reference
Unexecuted instantiation: <wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_reference
Unexecuted instantiation: <wasmer_compiler_cranelift::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_reference
Unexecuted instantiation: <wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_reference
129
130
    /// Write a u8.
131
2.01M
    fn write_u8(&mut self, val: u8) -> Result<()> {
132
2.01M
        let bytes = [val];
133
2.01M
        self.write(&bytes)
134
2.01M
    }
Unexecuted instantiation: <gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_u8
Unexecuted instantiation: <wasmer_compiler_cranelift::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_u8
Unexecuted instantiation: <_ as gimli::write::writer::Writer>::write_u8
<wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_u8
Line
Count
Source
131
403k
    fn write_u8(&mut self, val: u8) -> Result<()> {
132
403k
        let bytes = [val];
133
403k
        self.write(&bytes)
134
403k
    }
Unexecuted instantiation: <gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_u8
<wasmer_compiler_cranelift::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_u8
Line
Count
Source
131
1.60M
    fn write_u8(&mut self, val: u8) -> Result<()> {
132
1.60M
        let bytes = [val];
133
1.60M
        self.write(&bytes)
134
1.60M
    }
Unexecuted instantiation: <wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_u8
135
136
    /// Write a u16.
137
0
    fn write_u16(&mut self, val: u16) -> Result<()> {
138
0
        let mut bytes = [0; 2];
139
0
        self.endian().write_u16(&mut bytes, val);
140
0
        self.write(&bytes)
141
0
    }
Unexecuted instantiation: <gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_u16
Unexecuted instantiation: <wasmer_compiler_cranelift::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_u16
Unexecuted instantiation: <_ as gimli::write::writer::Writer>::write_u16
Unexecuted instantiation: <wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_u16
Unexecuted instantiation: <gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_u16
Unexecuted instantiation: <wasmer_compiler_cranelift::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_u16
Unexecuted instantiation: <wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_u16
142
143
    /// Write a u32.
144
297k
    fn write_u32(&mut self, val: u32) -> Result<()> {
145
297k
        let mut bytes = [0; 4];
146
297k
        self.endian().write_u32(&mut bytes, val);
147
297k
        self.write(&bytes)
148
297k
    }
Unexecuted instantiation: <gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_u32
Unexecuted instantiation: <wasmer_compiler_cranelift::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_u32
Unexecuted instantiation: <_ as gimli::write::writer::Writer>::write_u32
<gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_u32
Line
Count
Source
144
103
    fn write_u32(&mut self, val: u32) -> Result<()> {
145
103
        let mut bytes = [0; 4];
146
103
        self.endian().write_u32(&mut bytes, val);
147
103
        self.write(&bytes)
148
103
    }
<wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_u32
Line
Count
Source
144
51.4k
    fn write_u32(&mut self, val: u32) -> Result<()> {
145
51.4k
        let mut bytes = [0; 4];
146
51.4k
        self.endian().write_u32(&mut bytes, val);
147
51.4k
        self.write(&bytes)
148
51.4k
    }
<gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_u32
Line
Count
Source
144
2.04k
    fn write_u32(&mut self, val: u32) -> Result<()> {
145
2.04k
        let mut bytes = [0; 4];
146
2.04k
        self.endian().write_u32(&mut bytes, val);
147
2.04k
        self.write(&bytes)
148
2.04k
    }
<wasmer_compiler_cranelift::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_u32
Line
Count
Source
144
243k
    fn write_u32(&mut self, val: u32) -> Result<()> {
145
243k
        let mut bytes = [0; 4];
146
243k
        self.endian().write_u32(&mut bytes, val);
147
243k
        self.write(&bytes)
148
243k
    }
Unexecuted instantiation: <gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_u32
Unexecuted instantiation: <wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_u32
149
150
    /// Write a u64.
151
413k
    fn write_u64(&mut self, val: u64) -> Result<()> {
152
413k
        let mut bytes = [0; 8];
153
413k
        self.endian().write_u64(&mut bytes, val);
154
413k
        self.write(&bytes)
155
413k
    }
Unexecuted instantiation: <gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_u64
Unexecuted instantiation: <wasmer_compiler_cranelift::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_u64
Unexecuted instantiation: <_ as gimli::write::writer::Writer>::write_u64
<wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_u64
Line
Count
Source
151
51.2k
    fn write_u64(&mut self, val: u64) -> Result<()> {
152
51.2k
        let mut bytes = [0; 8];
153
51.2k
        self.endian().write_u64(&mut bytes, val);
154
51.2k
        self.write(&bytes)
155
51.2k
    }
Unexecuted instantiation: <gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_u64
<wasmer_compiler_cranelift::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_u64
Line
Count
Source
151
361k
    fn write_u64(&mut self, val: u64) -> Result<()> {
152
361k
        let mut bytes = [0; 8];
153
361k
        self.endian().write_u64(&mut bytes, val);
154
361k
        self.write(&bytes)
155
361k
    }
Unexecuted instantiation: <wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_u64
156
157
    /// Write a u128.
158
0
    fn write_u128(&mut self, val: u128) -> Result<()> {
159
0
        let mut bytes = [0; 16];
160
0
        self.endian().write_u128(&mut bytes, val);
161
0
        self.write(&bytes)
162
0
    }
163
164
    /// Write a u8 at the given offset.
165
121k
    fn write_u8_at(&mut self, offset: usize, val: u8) -> Result<()> {
166
121k
        let bytes = [val];
167
121k
        self.write_at(offset, &bytes)
168
121k
    }
Unexecuted instantiation: <wasmer_compiler_cranelift::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_u8_at
Unexecuted instantiation: <_ as gimli::write::writer::Writer>::write_u8_at
Unexecuted instantiation: <wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_u8_at
<wasmer_compiler_cranelift::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_u8_at
Line
Count
Source
165
121k
    fn write_u8_at(&mut self, offset: usize, val: u8) -> Result<()> {
166
121k
        let bytes = [val];
167
121k
        self.write_at(offset, &bytes)
168
121k
    }
Unexecuted instantiation: <wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_u8_at
169
170
    /// Write a u16 at the given offset.
171
0
    fn write_u16_at(&mut self, offset: usize, val: u16) -> Result<()> {
172
0
        let mut bytes = [0; 2];
173
0
        self.endian().write_u16(&mut bytes, val);
174
0
        self.write_at(offset, &bytes)
175
0
    }
Unexecuted instantiation: <wasmer_compiler_cranelift::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_u16_at
Unexecuted instantiation: <_ as gimli::write::writer::Writer>::write_u16_at
Unexecuted instantiation: <wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_u16_at
Unexecuted instantiation: <wasmer_compiler_cranelift::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_u16_at
Unexecuted instantiation: <wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_u16_at
176
177
    /// Write a u32 at the given offset.
178
147k
    fn write_u32_at(&mut self, offset: usize, val: u32) -> Result<()> {
179
147k
        let mut bytes = [0; 4];
180
147k
        self.endian().write_u32(&mut bytes, val);
181
147k
        self.write_at(offset, &bytes)
182
147k
    }
Unexecuted instantiation: <wasmer_compiler_cranelift::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_u32_at
Unexecuted instantiation: <_ as gimli::write::writer::Writer>::write_u32_at
<wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_u32_at
Line
Count
Source
178
25.7k
    fn write_u32_at(&mut self, offset: usize, val: u32) -> Result<()> {
179
25.7k
        let mut bytes = [0; 4];
180
25.7k
        self.endian().write_u32(&mut bytes, val);
181
25.7k
        self.write_at(offset, &bytes)
182
25.7k
    }
<wasmer_compiler_cranelift::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_u32_at
Line
Count
Source
178
121k
    fn write_u32_at(&mut self, offset: usize, val: u32) -> Result<()> {
179
121k
        let mut bytes = [0; 4];
180
121k
        self.endian().write_u32(&mut bytes, val);
181
121k
        self.write_at(offset, &bytes)
182
121k
    }
Unexecuted instantiation: <wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_u32_at
183
184
    /// Write a u64 at the given offset.
185
0
    fn write_u64_at(&mut self, offset: usize, val: u64) -> Result<()> {
186
0
        let mut bytes = [0; 8];
187
0
        self.endian().write_u64(&mut bytes, val);
188
0
        self.write_at(offset, &bytes)
189
0
    }
Unexecuted instantiation: <wasmer_compiler_cranelift::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_u64_at
Unexecuted instantiation: <_ as gimli::write::writer::Writer>::write_u64_at
Unexecuted instantiation: <wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_u64_at
Unexecuted instantiation: <wasmer_compiler_cranelift::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_u64_at
Unexecuted instantiation: <wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_u64_at
190
191
    /// Write a u128 at the given offset.
192
0
    fn write_u128_at(&mut self, offset: usize, val: u128) -> Result<()> {
193
0
        let mut bytes = [0; 16];
194
0
        self.endian().write_u128(&mut bytes, val);
195
0
        self.write_at(offset, &bytes)
196
0
    }
197
198
    /// Write unsigned data of the given size.
199
    ///
200
    /// Returns an error if the value is too large for the size.
201
    /// This must not be used directly for values that may require relocation.
202
706k
    fn write_udata(&mut self, val: u64, size: u8) -> Result<()> {
203
706k
        match size {
204
            1 => {
205
0
                let write_val = val as u8;
206
0
                if val != u64::from(write_val) {
207
0
                    return Err(Error::ValueTooLarge);
208
0
                }
209
0
                self.write_u8(write_val)
210
            }
211
            2 => {
212
0
                let write_val = val as u16;
213
0
                if val != u64::from(write_val) {
214
0
                    return Err(Error::ValueTooLarge);
215
0
                }
216
0
                self.write_u16(write_val)
217
            }
218
            4 => {
219
293k
                let write_val = val as u32;
220
293k
                if val != u64::from(write_val) {
221
0
                    return Err(Error::ValueTooLarge);
222
293k
                }
223
293k
                self.write_u32(write_val)
224
            }
225
413k
            8 => self.write_u64(val),
226
0
            otherwise => Err(Error::UnsupportedWordSize(otherwise)),
227
        }
228
706k
    }
Unexecuted instantiation: <gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_udata
Unexecuted instantiation: <wasmer_compiler_cranelift::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_udata
Unexecuted instantiation: <_ as gimli::write::writer::Writer>::write_udata
<wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_udata
Line
Count
Source
202
102k
    fn write_udata(&mut self, val: u64, size: u8) -> Result<()> {
203
102k
        match size {
204
            1 => {
205
0
                let write_val = val as u8;
206
0
                if val != u64::from(write_val) {
207
0
                    return Err(Error::ValueTooLarge);
208
0
                }
209
0
                self.write_u8(write_val)
210
            }
211
            2 => {
212
0
                let write_val = val as u16;
213
0
                if val != u64::from(write_val) {
214
0
                    return Err(Error::ValueTooLarge);
215
0
                }
216
0
                self.write_u16(write_val)
217
            }
218
            4 => {
219
51.3k
                let write_val = val as u32;
220
51.3k
                if val != u64::from(write_val) {
221
0
                    return Err(Error::ValueTooLarge);
222
51.3k
                }
223
51.3k
                self.write_u32(write_val)
224
            }
225
51.2k
            8 => self.write_u64(val),
226
0
            otherwise => Err(Error::UnsupportedWordSize(otherwise)),
227
        }
228
102k
    }
Unexecuted instantiation: <gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_udata
<wasmer_compiler_cranelift::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_udata
Line
Count
Source
202
603k
    fn write_udata(&mut self, val: u64, size: u8) -> Result<()> {
203
603k
        match size {
204
            1 => {
205
0
                let write_val = val as u8;
206
0
                if val != u64::from(write_val) {
207
0
                    return Err(Error::ValueTooLarge);
208
0
                }
209
0
                self.write_u8(write_val)
210
            }
211
            2 => {
212
0
                let write_val = val as u16;
213
0
                if val != u64::from(write_val) {
214
0
                    return Err(Error::ValueTooLarge);
215
0
                }
216
0
                self.write_u16(write_val)
217
            }
218
            4 => {
219
241k
                let write_val = val as u32;
220
241k
                if val != u64::from(write_val) {
221
0
                    return Err(Error::ValueTooLarge);
222
241k
                }
223
241k
                self.write_u32(write_val)
224
            }
225
361k
            8 => self.write_u64(val),
226
0
            otherwise => Err(Error::UnsupportedWordSize(otherwise)),
227
        }
228
603k
    }
Unexecuted instantiation: <wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_udata
229
230
    /// Write signed data of the given size.
231
    ///
232
    /// Returns an error if the value is too large for the size.
233
    /// This must not be used directly for values that may require relocation.
234
0
    fn write_sdata(&mut self, val: i64, size: u8) -> Result<()> {
235
0
        match size {
236
            1 => {
237
0
                let write_val = val as i8;
238
0
                if val != i64::from(write_val) {
239
0
                    return Err(Error::ValueTooLarge);
240
0
                }
241
0
                self.write_u8(write_val as u8)
242
            }
243
            2 => {
244
0
                let write_val = val as i16;
245
0
                if val != i64::from(write_val) {
246
0
                    return Err(Error::ValueTooLarge);
247
0
                }
248
0
                self.write_u16(write_val as u16)
249
            }
250
            4 => {
251
0
                let write_val = val as i32;
252
0
                if val != i64::from(write_val) {
253
0
                    return Err(Error::ValueTooLarge);
254
0
                }
255
0
                self.write_u32(write_val as u32)
256
            }
257
0
            8 => self.write_u64(val as u64),
258
0
            otherwise => Err(Error::UnsupportedWordSize(otherwise)),
259
        }
260
0
    }
Unexecuted instantiation: <gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_sdata
Unexecuted instantiation: <wasmer_compiler_cranelift::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_sdata
Unexecuted instantiation: <_ as gimli::write::writer::Writer>::write_sdata
Unexecuted instantiation: <wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_sdata
Unexecuted instantiation: <gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_sdata
Unexecuted instantiation: <wasmer_compiler_cranelift::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_sdata
Unexecuted instantiation: <wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_sdata
261
262
    /// Write a word of the given size at the given offset.
263
    ///
264
    /// Returns an error if the value is too large for the size.
265
    /// This must not be used directly for values that may require relocation.
266
269k
    fn write_udata_at(&mut self, offset: usize, val: u64, size: u8) -> Result<()> {
267
269k
        match size {
268
            1 => {
269
121k
                let write_val = val as u8;
270
121k
                if val != u64::from(write_val) {
271
0
                    return Err(Error::ValueTooLarge);
272
121k
                }
273
121k
                self.write_u8_at(offset, write_val)
274
            }
275
            2 => {
276
0
                let write_val = val as u16;
277
0
                if val != u64::from(write_val) {
278
0
                    return Err(Error::ValueTooLarge);
279
0
                }
280
0
                self.write_u16_at(offset, write_val)
281
            }
282
            4 => {
283
147k
                let write_val = val as u32;
284
147k
                if val != u64::from(write_val) {
285
0
                    return Err(Error::ValueTooLarge);
286
147k
                }
287
147k
                self.write_u32_at(offset, write_val)
288
            }
289
0
            8 => self.write_u64_at(offset, val),
290
0
            otherwise => Err(Error::UnsupportedWordSize(otherwise)),
291
        }
292
269k
    }
Unexecuted instantiation: <wasmer_compiler_cranelift::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_udata_at
Unexecuted instantiation: <_ as gimli::write::writer::Writer>::write_udata_at
<wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_udata_at
Line
Count
Source
266
25.7k
    fn write_udata_at(&mut self, offset: usize, val: u64, size: u8) -> Result<()> {
267
25.7k
        match size {
268
            1 => {
269
0
                let write_val = val as u8;
270
0
                if val != u64::from(write_val) {
271
0
                    return Err(Error::ValueTooLarge);
272
0
                }
273
0
                self.write_u8_at(offset, write_val)
274
            }
275
            2 => {
276
0
                let write_val = val as u16;
277
0
                if val != u64::from(write_val) {
278
0
                    return Err(Error::ValueTooLarge);
279
0
                }
280
0
                self.write_u16_at(offset, write_val)
281
            }
282
            4 => {
283
25.7k
                let write_val = val as u32;
284
25.7k
                if val != u64::from(write_val) {
285
0
                    return Err(Error::ValueTooLarge);
286
25.7k
                }
287
25.7k
                self.write_u32_at(offset, write_val)
288
            }
289
0
            8 => self.write_u64_at(offset, val),
290
0
            otherwise => Err(Error::UnsupportedWordSize(otherwise)),
291
        }
292
25.7k
    }
<wasmer_compiler_cranelift::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_udata_at
Line
Count
Source
266
243k
    fn write_udata_at(&mut self, offset: usize, val: u64, size: u8) -> Result<()> {
267
243k
        match size {
268
            1 => {
269
121k
                let write_val = val as u8;
270
121k
                if val != u64::from(write_val) {
271
0
                    return Err(Error::ValueTooLarge);
272
121k
                }
273
121k
                self.write_u8_at(offset, write_val)
274
            }
275
            2 => {
276
0
                let write_val = val as u16;
277
0
                if val != u64::from(write_val) {
278
0
                    return Err(Error::ValueTooLarge);
279
0
                }
280
0
                self.write_u16_at(offset, write_val)
281
            }
282
            4 => {
283
121k
                let write_val = val as u32;
284
121k
                if val != u64::from(write_val) {
285
0
                    return Err(Error::ValueTooLarge);
286
121k
                }
287
121k
                self.write_u32_at(offset, write_val)
288
            }
289
0
            8 => self.write_u64_at(offset, val),
290
0
            otherwise => Err(Error::UnsupportedWordSize(otherwise)),
291
        }
292
243k
    }
Unexecuted instantiation: <wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_udata_at
293
294
    /// Write an unsigned LEB128 encoded integer.
295
613k
    fn write_uleb128(&mut self, val: u64) -> Result<()> {
296
613k
        self.write(Leb128::unsigned(val).bytes())
297
613k
    }
Unexecuted instantiation: <gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_uleb128
Unexecuted instantiation: <wasmer_compiler_cranelift::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_uleb128
Unexecuted instantiation: <_ as gimli::write::writer::Writer>::write_uleb128
<wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_uleb128
Line
Count
Source
295
196k
    fn write_uleb128(&mut self, val: u64) -> Result<()> {
296
196k
        self.write(Leb128::unsigned(val).bytes())
297
196k
    }
Unexecuted instantiation: <gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_uleb128
<wasmer_compiler_cranelift::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_uleb128
Line
Count
Source
295
416k
    fn write_uleb128(&mut self, val: u64) -> Result<()> {
296
416k
        self.write(Leb128::unsigned(val).bytes())
297
416k
    }
Unexecuted instantiation: <wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_uleb128
298
299
    /// Write a signed LEB128 encoded integer.
300
2.14k
    fn write_sleb128(&mut self, val: i64) -> Result<()> {
301
2.14k
        self.write(Leb128::signed(val).bytes())
302
2.14k
    }
Unexecuted instantiation: <gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_sleb128
Unexecuted instantiation: <wasmer_compiler_cranelift::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_sleb128
Unexecuted instantiation: <_ as gimli::write::writer::Writer>::write_sleb128
<wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_sleb128
Line
Count
Source
300
103
    fn write_sleb128(&mut self, val: i64) -> Result<()> {
301
103
        self.write(Leb128::signed(val).bytes())
302
103
    }
Unexecuted instantiation: <gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_sleb128
<wasmer_compiler_cranelift::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_sleb128
Line
Count
Source
300
2.04k
    fn write_sleb128(&mut self, val: i64) -> Result<()> {
301
2.04k
        self.write(Leb128::signed(val).bytes())
302
2.04k
    }
Unexecuted instantiation: <wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_sleb128
303
304
    /// Write an initial length according to the given DWARF format.
305
    ///
306
    /// This will only write a length of zero, since the length isn't
307
    /// known yet, and a subsequent call to `write_initial_length_at`
308
    /// will write the actual length.
309
147k
    fn write_initial_length(&mut self, format: Format) -> Result<InitialLengthOffset> {
310
147k
        if format == Format::Dwarf64 {
311
0
            self.write_u32(0xffff_ffff)?;
312
147k
        }
313
147k
        let offset = InitialLengthOffset(self.len());
314
147k
        self.write_udata(0, format.word_size())?;
315
147k
        Ok(offset)
316
147k
    }
Unexecuted instantiation: <wasmer_compiler_cranelift::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_initial_length
Unexecuted instantiation: <_ as gimli::write::writer::Writer>::write_initial_length
<wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_initial_length
Line
Count
Source
309
25.7k
    fn write_initial_length(&mut self, format: Format) -> Result<InitialLengthOffset> {
310
25.7k
        if format == Format::Dwarf64 {
311
0
            self.write_u32(0xffff_ffff)?;
312
25.7k
        }
313
25.7k
        let offset = InitialLengthOffset(self.len());
314
25.7k
        self.write_udata(0, format.word_size())?;
315
25.7k
        Ok(offset)
316
25.7k
    }
<wasmer_compiler_cranelift::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_initial_length
Line
Count
Source
309
121k
    fn write_initial_length(&mut self, format: Format) -> Result<InitialLengthOffset> {
310
121k
        if format == Format::Dwarf64 {
311
0
            self.write_u32(0xffff_ffff)?;
312
121k
        }
313
121k
        let offset = InitialLengthOffset(self.len());
314
121k
        self.write_udata(0, format.word_size())?;
315
121k
        Ok(offset)
316
121k
    }
Unexecuted instantiation: <wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_initial_length
317
318
    /// Write an initial length at the given offset according to the given DWARF format.
319
    ///
320
    /// `write_initial_length` must have previously returned the offset.
321
147k
    fn write_initial_length_at(
322
147k
        &mut self,
323
147k
        offset: InitialLengthOffset,
324
147k
        length: u64,
325
147k
        format: Format,
326
147k
    ) -> Result<()> {
327
147k
        self.write_udata_at(offset.0, length, format.word_size())
328
147k
    }
Unexecuted instantiation: <wasmer_compiler_cranelift::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_initial_length_at
Unexecuted instantiation: <_ as gimli::write::writer::Writer>::write_initial_length_at
<wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_initial_length_at
Line
Count
Source
321
25.7k
    fn write_initial_length_at(
322
25.7k
        &mut self,
323
25.7k
        offset: InitialLengthOffset,
324
25.7k
        length: u64,
325
25.7k
        format: Format,
326
25.7k
    ) -> Result<()> {
327
25.7k
        self.write_udata_at(offset.0, length, format.word_size())
328
25.7k
    }
<wasmer_compiler_cranelift::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_initial_length_at
Line
Count
Source
321
121k
    fn write_initial_length_at(
322
121k
        &mut self,
323
121k
        offset: InitialLengthOffset,
324
121k
        length: u64,
325
121k
        format: Format,
326
121k
    ) -> Result<()> {
327
121k
        self.write_udata_at(offset.0, length, format.word_size())
328
121k
    }
Unexecuted instantiation: <wasmer_compiler_singlepass::dwarf::WriterRelocate as gimli::write::writer::Writer>::write_initial_length_at
329
}
330
331
/// The offset at which an initial length should be written.
332
#[derive(Debug, Clone, Copy)]
333
pub struct InitialLengthOffset(usize);
334
335
#[cfg(test)]
336
mod tests {
337
    use super::*;
338
    use crate::write;
339
    use crate::{BigEndian, LittleEndian};
340
341
    #[test]
342
    fn test_writer() {
343
        let mut w = write::EndianVec::new(LittleEndian);
344
        w.write_address(Address::Constant(0x1122_3344), 4).unwrap();
345
        assert_eq!(w.slice(), &[0x44, 0x33, 0x22, 0x11]);
346
        assert_eq!(
347
            w.write_address(
348
                Address::Symbol {
349
                    symbol: 0,
350
                    addend: 0
351
                },
352
                4
353
            ),
354
            Err(Error::InvalidAddress)
355
        );
356
357
        let mut w = write::EndianVec::new(LittleEndian);
358
        w.write_offset(0x1122_3344, SectionId::DebugInfo, 4)
359
            .unwrap();
360
        assert_eq!(w.slice(), &[0x44, 0x33, 0x22, 0x11]);
361
        w.write_offset_at(1, 0x5566, SectionId::DebugInfo, 2)
362
            .unwrap();
363
        assert_eq!(w.slice(), &[0x44, 0x66, 0x55, 0x11]);
364
365
        let mut w = write::EndianVec::new(LittleEndian);
366
        w.write_u8(0x11).unwrap();
367
        w.write_u16(0x2233).unwrap();
368
        w.write_u32(0x4455_6677).unwrap();
369
        w.write_u64(0x8081_8283_8485_8687).unwrap();
370
        #[rustfmt::skip]
371
        assert_eq!(w.slice(), &[
372
            0x11,
373
            0x33, 0x22,
374
            0x77, 0x66, 0x55, 0x44,
375
            0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80,
376
        ]);
377
        w.write_u8_at(14, 0x11).unwrap();
378
        w.write_u16_at(12, 0x2233).unwrap();
379
        w.write_u32_at(8, 0x4455_6677).unwrap();
380
        w.write_u64_at(0, 0x8081_8283_8485_8687).unwrap();
381
        #[rustfmt::skip]
382
        assert_eq!(w.slice(), &[
383
            0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80,
384
            0x77, 0x66, 0x55, 0x44,
385
            0x33, 0x22,
386
            0x11,
387
        ]);
388
389
        let mut w = write::EndianVec::new(BigEndian);
390
        w.write_u8(0x11).unwrap();
391
        w.write_u16(0x2233).unwrap();
392
        w.write_u32(0x4455_6677).unwrap();
393
        w.write_u64(0x8081_8283_8485_8687).unwrap();
394
        #[rustfmt::skip]
395
        assert_eq!(w.slice(), &[
396
            0x11,
397
            0x22, 0x33,
398
            0x44, 0x55, 0x66, 0x77,
399
            0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
400
        ]);
401
        w.write_u8_at(14, 0x11).unwrap();
402
        w.write_u16_at(12, 0x2233).unwrap();
403
        w.write_u32_at(8, 0x4455_6677).unwrap();
404
        w.write_u64_at(0, 0x8081_8283_8485_8687).unwrap();
405
        #[rustfmt::skip]
406
        assert_eq!(w.slice(), &[
407
            0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
408
            0x44, 0x55, 0x66, 0x77,
409
            0x22, 0x33,
410
            0x11,
411
        ]);
412
413
        let mut w = write::EndianVec::new(LittleEndian);
414
        w.write_udata(0x11, 1).unwrap();
415
        w.write_udata(0x2233, 2).unwrap();
416
        w.write_udata(0x4455_6677, 4).unwrap();
417
        w.write_udata(0x8081_8283_8485_8687, 8).unwrap();
418
        #[rustfmt::skip]
419
        assert_eq!(w.slice(), &[
420
            0x11,
421
            0x33, 0x22,
422
            0x77, 0x66, 0x55, 0x44,
423
            0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80,
424
        ]);
425
        assert_eq!(w.write_udata(0x100, 1), Err(Error::ValueTooLarge));
426
        assert_eq!(w.write_udata(0x1_0000, 2), Err(Error::ValueTooLarge));
427
        assert_eq!(w.write_udata(0x1_0000_0000, 4), Err(Error::ValueTooLarge));
428
        assert_eq!(w.write_udata(0x00, 3), Err(Error::UnsupportedWordSize(3)));
429
        w.write_udata_at(14, 0x11, 1).unwrap();
430
        w.write_udata_at(12, 0x2233, 2).unwrap();
431
        w.write_udata_at(8, 0x4455_6677, 4).unwrap();
432
        w.write_udata_at(0, 0x8081_8283_8485_8687, 8).unwrap();
433
        #[rustfmt::skip]
434
        assert_eq!(w.slice(), &[
435
            0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80,
436
            0x77, 0x66, 0x55, 0x44,
437
            0x33, 0x22,
438
            0x11,
439
        ]);
440
        assert_eq!(w.write_udata_at(0, 0x100, 1), Err(Error::ValueTooLarge));
441
        assert_eq!(w.write_udata_at(0, 0x1_0000, 2), Err(Error::ValueTooLarge));
442
        assert_eq!(
443
            w.write_udata_at(0, 0x1_0000_0000, 4),
444
            Err(Error::ValueTooLarge)
445
        );
446
        assert_eq!(
447
            w.write_udata_at(0, 0x00, 3),
448
            Err(Error::UnsupportedWordSize(3))
449
        );
450
451
        let mut w = write::EndianVec::new(LittleEndian);
452
        w.write_uleb128(0).unwrap();
453
        assert_eq!(w.slice(), &[0]);
454
455
        let mut w = write::EndianVec::new(LittleEndian);
456
        w.write_uleb128(u64::MAX).unwrap();
457
        assert_eq!(
458
            w.slice(),
459
            &[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1]
460
        );
461
462
        let mut w = write::EndianVec::new(LittleEndian);
463
        w.write_sleb128(0).unwrap();
464
        assert_eq!(w.slice(), &[0]);
465
466
        let mut w = write::EndianVec::new(LittleEndian);
467
        w.write_sleb128(i64::MAX).unwrap();
468
        assert_eq!(
469
            w.slice(),
470
            &[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0]
471
        );
472
473
        let mut w = write::EndianVec::new(LittleEndian);
474
        w.write_sleb128(i64::MIN).unwrap();
475
        assert_eq!(
476
            w.slice(),
477
            &[0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f]
478
        );
479
480
        let mut w = write::EndianVec::new(LittleEndian);
481
        let offset = w.write_initial_length(Format::Dwarf32).unwrap();
482
        assert_eq!(w.slice(), &[0, 0, 0, 0]);
483
        w.write_initial_length_at(offset, 0x1122_3344, Format::Dwarf32)
484
            .unwrap();
485
        assert_eq!(w.slice(), &[0x44, 0x33, 0x22, 0x11]);
486
        assert_eq!(
487
            w.write_initial_length_at(offset, 0x1_0000_0000, Format::Dwarf32),
488
            Err(Error::ValueTooLarge)
489
        );
490
491
        let mut w = write::EndianVec::new(LittleEndian);
492
        let offset = w.write_initial_length(Format::Dwarf64).unwrap();
493
        assert_eq!(w.slice(), &[0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0]);
494
        w.write_initial_length_at(offset, 0x1122_3344_5566_7788, Format::Dwarf64)
495
            .unwrap();
496
        assert_eq!(
497
            w.slice(),
498
            &[
499
                0xff, 0xff, 0xff, 0xff, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11
500
            ]
501
        );
502
    }
503
}