Coverage Report

Created: 2021-03-22 08:29

/rust/registry/src/github.com-1ecc6299db9ec823/gimli-0.23.0/src/write/writer.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::common::{Format, SectionId};
2
use crate::constants;
3
use crate::endianity::Endianity;
4
use crate::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
1.87M
    fn write_address(&mut self, address: Address, size: u8) -> Result<()> {
37
1.87M
        match address {
38
1.87M
            Address::Constant(val) => self.write_udata(val, size),
39
0
            Address::Symbol { .. } => Err(Error::InvalidAddress),
40
        }
41
1.87M
    }
<gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_address
Line
Count
Source
36
1.87M
    fn write_address(&mut self, address: Address, size: u8) -> Result<()> {
37
1.87M
        match address {
38
1.87M
            Address::Constant(val) => self.write_udata(val, size),
39
0
            Address::Symbol { .. } => Err(Error::InvalidAddress),
40
        }
41
1.87M
    }
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
                        offset.wrapping_sub(val)
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: <wasmtime_debug::write_debuginfo::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
            _ => {
97
0
                return Err(Error::UnsupportedPointerEncoding(format));
98
            }
99
        }
100
0
    }
Unexecuted instantiation: <gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_eh_pointer_data
Unexecuted instantiation: <wasmtime_debug::write_debuginfo::WriterRelocate as gimli::write::writer::Writer>::write_eh_pointer_data
101
102
    /// Write an offset that is relative to the start of the given section.
103
    ///
104
    /// If the writer supports relocations, then it must provide its own implementation
105
    /// of this method.
106
0
    fn write_offset(&mut self, val: usize, _section: SectionId, size: u8) -> Result<()> {
107
0
        self.write_udata(val as u64, size)
108
0
    }
109
110
    /// Write an offset that is relative to the start of the given section.
111
    ///
112
    /// If the writer supports relocations, then it must provide its own implementation
113
    /// of this method.
114
0
    fn write_offset_at(
115
0
        &mut self,
116
0
        offset: usize,
117
0
        val: usize,
118
0
        _section: SectionId,
119
0
        size: u8,
120
0
    ) -> Result<()> {
121
0
        self.write_udata_at(offset, val as u64, size)
122
0
    }
123
124
    /// Write a reference to a symbol.
125
    ///
126
    /// If the writer supports symbols, then it must provide its own implementation
127
    /// of this method.
128
0
    fn write_reference(&mut self, _symbol: usize, _size: u8) -> Result<()> {
129
0
        Err(Error::InvalidReference)
130
0
    }
131
132
    /// Write a u8.
133
29.0M
    fn write_u8(&mut self, val: u8) -> Result<()> {
134
29.0M
        let bytes = [val];
135
29.0M
        self.write(&bytes)
136
29.0M
    }
<wasmtime_debug::write_debuginfo::WriterRelocate as gimli::write::writer::Writer>::write_u8
Line
Count
Source
133
7.46M
    fn write_u8(&mut self, val: u8) -> Result<()> {
134
7.46M
        let bytes = [val];
135
7.46M
        self.write(&bytes)
136
7.46M
    }
<gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_u8
Line
Count
Source
133
21.6M
    fn write_u8(&mut self, val: u8) -> Result<()> {
134
21.6M
        let bytes = [val];
135
21.6M
        self.write(&bytes)
136
21.6M
    }
137
138
    /// Write a u16.
139
638k
    fn write_u16(&mut self, val: u16) -> Result<()> {
140
638k
        let mut bytes = [0; 2];
141
638k
        self.endian().write_u16(&mut bytes, val);
142
638k
        self.write(&bytes)
143
638k
    }
<gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_u16
Line
Count
Source
139
68.0k
    fn write_u16(&mut self, val: u16) -> Result<()> {
140
68.0k
        let mut bytes = [0; 2];
141
68.0k
        self.endian().write_u16(&mut bytes, val);
142
68.0k
        self.write(&bytes)
143
68.0k
    }
<wasmtime_debug::write_debuginfo::WriterRelocate as gimli::write::writer::Writer>::write_u16
Line
Count
Source
139
570k
    fn write_u16(&mut self, val: u16) -> Result<()> {
140
570k
        let mut bytes = [0; 2];
141
570k
        self.endian().write_u16(&mut bytes, val);
142
570k
        self.write(&bytes)
143
570k
    }
144
145
    /// Write a u32.
146
4.60M
    fn write_u32(&mut self, val: u32) -> Result<()> {
147
4.60M
        let mut bytes = [0; 4];
148
4.60M
        self.endian().write_u32(&mut bytes, val);
149
4.60M
        self.write(&bytes)
150
4.60M
    }
<wasmtime_debug::write_debuginfo::WriterRelocate as gimli::write::writer::Writer>::write_u32
Line
Count
Source
146
617k
    fn write_u32(&mut self, val: u32) -> Result<()> {
147
617k
        let mut bytes = [0; 4];
148
617k
        self.endian().write_u32(&mut bytes, val);
149
617k
        self.write(&bytes)
150
617k
    }
<gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_u32
Line
Count
Source
146
3.99M
    fn write_u32(&mut self, val: u32) -> Result<()> {
147
3.99M
        let mut bytes = [0; 4];
148
3.99M
        self.endian().write_u32(&mut bytes, val);
149
3.99M
        self.write(&bytes)
150
3.99M
    }
151
152
    /// Write a u64.
153
4.94M
    fn write_u64(&mut self, val: u64) -> Result<()> {
154
4.94M
        let mut bytes = [0; 8];
155
4.94M
        self.endian().write_u64(&mut bytes, val);
156
4.94M
        self.write(&bytes)
157
4.94M
    }
<gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_u64
Line
Count
Source
153
3.75M
    fn write_u64(&mut self, val: u64) -> Result<()> {
154
3.75M
        let mut bytes = [0; 8];
155
3.75M
        self.endian().write_u64(&mut bytes, val);
156
3.75M
        self.write(&bytes)
157
3.75M
    }
<wasmtime_debug::write_debuginfo::WriterRelocate as gimli::write::writer::Writer>::write_u64
Line
Count
Source
153
1.18M
    fn write_u64(&mut self, val: u64) -> Result<()> {
154
1.18M
        let mut bytes = [0; 8];
155
1.18M
        self.endian().write_u64(&mut bytes, val);
156
1.18M
        self.write(&bytes)
157
1.18M
    }
158
159
    /// Write a u8 at the given offset.
160
0
    fn write_u8_at(&mut self, offset: usize, val: u8) -> Result<()> {
161
0
        let bytes = [val];
162
0
        self.write_at(offset, &bytes)
163
0
    }
164
165
    /// Write a u16 at the given offset.
166
0
    fn write_u16_at(&mut self, offset: usize, val: u16) -> Result<()> {
167
0
        let mut bytes = [0; 2];
168
0
        self.endian().write_u16(&mut bytes, val);
169
0
        self.write_at(offset, &bytes)
170
0
    }
171
172
    /// Write a u32 at the given offset.
173
2.14M
    fn write_u32_at(&mut self, offset: usize, val: u32) -> Result<()> {
174
2.14M
        let mut bytes = [0; 4];
175
2.14M
        self.endian().write_u32(&mut bytes, val);
176
2.14M
        self.write_at(offset, &bytes)
177
2.14M
    }
<gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_u32_at
Line
Count
Source
173
1.95M
    fn write_u32_at(&mut self, offset: usize, val: u32) -> Result<()> {
174
1.95M
        let mut bytes = [0; 4];
175
1.95M
        self.endian().write_u32(&mut bytes, val);
176
1.95M
        self.write_at(offset, &bytes)
177
1.95M
    }
<wasmtime_debug::write_debuginfo::WriterRelocate as gimli::write::writer::Writer>::write_u32_at
Line
Count
Source
173
188k
    fn write_u32_at(&mut self, offset: usize, val: u32) -> Result<()> {
174
188k
        let mut bytes = [0; 4];
175
188k
        self.endian().write_u32(&mut bytes, val);
176
188k
        self.write_at(offset, &bytes)
177
188k
    }
178
179
    /// Write a u64 at the given offset.
180
0
    fn write_u64_at(&mut self, offset: usize, val: u64) -> Result<()> {
181
0
        let mut bytes = [0; 8];
182
0
        self.endian().write_u64(&mut bytes, val);
183
0
        self.write_at(offset, &bytes)
184
0
    }
185
186
    /// Write unsigned data of the given size.
187
    ///
188
    /// Returns an error if the value is too large for the size.
189
    /// This must not be used directly for values that may require relocation.
190
9.88M
    fn write_udata(&mut self, val: u64, size: u8) -> Result<()> {
191
9.88M
        match size {
192
            1 => {
193
0
                let write_val = val as u8;
194
0
                if val != u64::from(write_val) {
195
0
                    return Err(Error::ValueTooLarge);
196
0
                }
197
0
                self.write_u8(write_val)
198
            }
199
            2 => {
200
530k
                let write_val = val as u16;
201
530k
                if val != u64::from(write_val) {
202
0
                    return Err(Error::ValueTooLarge);
203
530k
                }
204
530k
                self.write_u16(write_val)
205
            }
206
            4 => {
207
4.41M
                let write_val = val as u32;
208
4.41M
                if val != u64::from(write_val) {
209
0
                    return Err(Error::ValueTooLarge);
210
4.41M
                }
211
4.41M
                self.write_u32(write_val)
212
            }
213
4.94M
            8 => self.write_u64(val),
214
0
            otherwise => Err(Error::UnsupportedWordSize(otherwise)),
215
        }
216
9.88M
    }
<gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_udata
Line
Count
Source
190
7.58M
    fn write_udata(&mut self, val: u64, size: u8) -> Result<()> {
191
7.58M
        match size {
192
            1 => {
193
0
                let write_val = val as u8;
194
0
                if val != u64::from(write_val) {
195
0
                    return Err(Error::ValueTooLarge);
196
0
                }
197
0
                self.write_u8(write_val)
198
            }
199
            2 => {
200
0
                let write_val = val as u16;
201
0
                if val != u64::from(write_val) {
202
0
                    return Err(Error::ValueTooLarge);
203
0
                }
204
0
                self.write_u16(write_val)
205
            }
206
            4 => {
207
3.83M
                let write_val = val as u32;
208
3.83M
                if val != u64::from(write_val) {
209
0
                    return Err(Error::ValueTooLarge);
210
3.83M
                }
211
3.83M
                self.write_u32(write_val)
212
            }
213
3.75M
            8 => self.write_u64(val),
214
0
            otherwise => Err(Error::UnsupportedWordSize(otherwise)),
215
        }
216
7.58M
    }
<wasmtime_debug::write_debuginfo::WriterRelocate as gimli::write::writer::Writer>::write_udata
Line
Count
Source
190
2.29M
    fn write_udata(&mut self, val: u64, size: u8) -> Result<()> {
191
2.29M
        match size {
192
            1 => {
193
0
                let write_val = val as u8;
194
0
                if val != u64::from(write_val) {
195
0
                    return Err(Error::ValueTooLarge);
196
0
                }
197
0
                self.write_u8(write_val)
198
            }
199
            2 => {
200
530k
                let write_val = val as u16;
201
530k
                if val != u64::from(write_val) {
202
0
                    return Err(Error::ValueTooLarge);
203
530k
                }
204
530k
                self.write_u16(write_val)
205
            }
206
            4 => {
207
582k
                let write_val = val as u32;
208
582k
                if val != u64::from(write_val) {
209
0
                    return Err(Error::ValueTooLarge);
210
582k
                }
211
582k
                self.write_u32(write_val)
212
            }
213
1.18M
            8 => self.write_u64(val),
214
0
            otherwise => Err(Error::UnsupportedWordSize(otherwise)),
215
        }
216
2.29M
    }
217
218
    /// Write signed data of the given size.
219
    ///
220
    /// Returns an error if the value is too large for the size.
221
    /// This must not be used directly for values that may require relocation.
222
0
    fn write_sdata(&mut self, val: i64, size: u8) -> Result<()> {
223
0
        match size {
224
            1 => {
225
0
                let write_val = val as i8;
226
0
                if val != i64::from(write_val) {
227
0
                    return Err(Error::ValueTooLarge);
228
0
                }
229
0
                self.write_u8(write_val as u8)
230
            }
231
            2 => {
232
0
                let write_val = val as i16;
233
0
                if val != i64::from(write_val) {
234
0
                    return Err(Error::ValueTooLarge);
235
0
                }
236
0
                self.write_u16(write_val as u16)
237
            }
238
            4 => {
239
0
                let write_val = val as i32;
240
0
                if val != i64::from(write_val) {
241
0
                    return Err(Error::ValueTooLarge);
242
0
                }
243
0
                self.write_u32(write_val as u32)
244
            }
245
0
            8 => self.write_u64(val as u64),
246
0
            otherwise => Err(Error::UnsupportedWordSize(otherwise)),
247
        }
248
0
    }
Unexecuted instantiation: <gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_sdata
Unexecuted instantiation: <wasmtime_debug::write_debuginfo::WriterRelocate as gimli::write::writer::Writer>::write_sdata
249
250
    /// Write a word of the given size at the given offset.
251
    ///
252
    /// Returns an error if the value is too large for the size.
253
    /// This must not be used directly for values that may require relocation.
254
2.14M
    fn write_udata_at(&mut self, offset: usize, val: u64, size: u8) -> Result<()> {
255
2.14M
        match size {
256
            1 => {
257
0
                let write_val = val as u8;
258
0
                if val != u64::from(write_val) {
259
0
                    return Err(Error::ValueTooLarge);
260
0
                }
261
0
                self.write_u8_at(offset, write_val)
262
            }
263
            2 => {
264
0
                let write_val = val as u16;
265
0
                if val != u64::from(write_val) {
266
0
                    return Err(Error::ValueTooLarge);
267
0
                }
268
0
                self.write_u16_at(offset, write_val)
269
            }
270
            4 => {
271
2.14M
                let write_val = val as u32;
272
2.14M
                if val != u64::from(write_val) {
273
0
                    return Err(Error::ValueTooLarge);
274
2.14M
                }
275
2.14M
                self.write_u32_at(offset, write_val)
276
            }
277
0
            8 => self.write_u64_at(offset, val),
278
0
            otherwise => Err(Error::UnsupportedWordSize(otherwise)),
279
        }
280
2.14M
    }
<gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_udata_at
Line
Count
Source
254
1.95M
    fn write_udata_at(&mut self, offset: usize, val: u64, size: u8) -> Result<()> {
255
1.95M
        match size {
256
            1 => {
257
0
                let write_val = val as u8;
258
0
                if val != u64::from(write_val) {
259
0
                    return Err(Error::ValueTooLarge);
260
0
                }
261
0
                self.write_u8_at(offset, write_val)
262
            }
263
            2 => {
264
0
                let write_val = val as u16;
265
0
                if val != u64::from(write_val) {
266
0
                    return Err(Error::ValueTooLarge);
267
0
                }
268
0
                self.write_u16_at(offset, write_val)
269
            }
270
            4 => {
271
1.95M
                let write_val = val as u32;
272
1.95M
                if val != u64::from(write_val) {
273
0
                    return Err(Error::ValueTooLarge);
274
1.95M
                }
275
1.95M
                self.write_u32_at(offset, write_val)
276
            }
277
0
            8 => self.write_u64_at(offset, val),
278
0
            otherwise => Err(Error::UnsupportedWordSize(otherwise)),
279
        }
280
1.95M
    }
<wasmtime_debug::write_debuginfo::WriterRelocate as gimli::write::writer::Writer>::write_udata_at
Line
Count
Source
254
188k
    fn write_udata_at(&mut self, offset: usize, val: u64, size: u8) -> Result<()> {
255
188k
        match size {
256
            1 => {
257
0
                let write_val = val as u8;
258
0
                if val != u64::from(write_val) {
259
0
                    return Err(Error::ValueTooLarge);
260
0
                }
261
0
                self.write_u8_at(offset, write_val)
262
            }
263
            2 => {
264
0
                let write_val = val as u16;
265
0
                if val != u64::from(write_val) {
266
0
                    return Err(Error::ValueTooLarge);
267
0
                }
268
0
                self.write_u16_at(offset, write_val)
269
            }
270
            4 => {
271
188k
                let write_val = val as u32;
272
188k
                if val != u64::from(write_val) {
273
0
                    return Err(Error::ValueTooLarge);
274
188k
                }
275
188k
                self.write_u32_at(offset, write_val)
276
            }
277
0
            8 => self.write_u64_at(offset, val),
278
0
            otherwise => Err(Error::UnsupportedWordSize(otherwise)),
279
        }
280
188k
    }
281
282
    /// Write an unsigned LEB128 encoded integer.
283
16.3M
    fn write_uleb128(&mut self, val: u64) -> Result<()> {
284
16.3M
        let mut bytes = [0u8; 10];
285
16.3M
        // bytes is long enough so this will never fail.
286
16.3M
        let len = leb128::write::unsigned(&mut { &mut bytes[..] }, val).unwrap();
287
16.3M
        self.write(&bytes[..len])
288
16.3M
    }
<wasmtime_debug::write_debuginfo::WriterRelocate as gimli::write::writer::Writer>::write_uleb128
Line
Count
Source
283
4.16M
    fn write_uleb128(&mut self, val: u64) -> Result<()> {
284
4.16M
        let mut bytes = [0u8; 10];
285
4.16M
        // bytes is long enough so this will never fail.
286
4.16M
        let len = leb128::write::unsigned(&mut { &mut bytes[..] }, val).unwrap();
287
4.16M
        self.write(&bytes[..len])
288
4.16M
    }
<gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_uleb128
Line
Count
Source
283
12.1M
    fn write_uleb128(&mut self, val: u64) -> Result<()> {
284
12.1M
        let mut bytes = [0u8; 10];
285
12.1M
        // bytes is long enough so this will never fail.
286
12.1M
        let len = leb128::write::unsigned(&mut { &mut bytes[..] }, val).unwrap();
287
12.1M
        self.write(&bytes[..len])
288
12.1M
    }
289
290
    /// Read an unsigned LEB128 encoded integer.
291
637k
    fn write_sleb128(&mut self, val: i64) -> Result<()> {
292
637k
        let mut bytes = [0u8; 10];
293
637k
        // bytes is long enough so this will never fail.
294
637k
        let len = leb128::write::signed(&mut { &mut bytes[..] }, val).unwrap();
295
637k
        self.write(&bytes[..len])
296
637k
    }
<wasmtime_debug::write_debuginfo::WriterRelocate as gimli::write::writer::Writer>::write_sleb128
Line
Count
Source
291
61.9k
    fn write_sleb128(&mut self, val: i64) -> Result<()> {
292
61.9k
        let mut bytes = [0u8; 10];
293
61.9k
        // bytes is long enough so this will never fail.
294
61.9k
        let len = leb128::write::signed(&mut { &mut bytes[..] }, val).unwrap();
295
61.9k
        self.write(&bytes[..len])
296
61.9k
    }
<gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_sleb128
Line
Count
Source
291
575k
    fn write_sleb128(&mut self, val: i64) -> Result<()> {
292
575k
        let mut bytes = [0u8; 10];
293
575k
        // bytes is long enough so this will never fail.
294
575k
        let len = leb128::write::signed(&mut { &mut bytes[..] }, val).unwrap();
295
575k
        self.write(&bytes[..len])
296
575k
    }
297
298
    /// Write an initial length according to the given DWARF format.
299
    ///
300
    /// This will only write a length of zero, since the length isn't
301
    /// known yet, and a subsequent call to `write_initial_length_at`
302
    /// will write the actual length.
303
2.02M
    fn write_initial_length(&mut self, format: Format) -> Result<InitialLengthOffset> {
304
2.02M
        if format == Format::Dwarf64 {
305
0
            self.write_u32(0xffff_ffff)?;
306
2.02M
        }
307
2.02M
        let offset = InitialLengthOffset(self.len());
308
2.02M
        self.write_udata(0, format.word_size())?;
309
2.02M
        Ok(offset)
310
2.02M
    }
<gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_initial_length
Line
Count
Source
303
1.95M
    fn write_initial_length(&mut self, format: Format) -> Result<InitialLengthOffset> {
304
1.95M
        if format == Format::Dwarf64 {
305
0
            self.write_u32(0xffff_ffff)?;
306
1.95M
        }
307
1.95M
        let offset = InitialLengthOffset(self.len());
308
1.95M
        self.write_udata(0, format.word_size())?;
309
1.95M
        Ok(offset)
310
1.95M
    }
<wasmtime_debug::write_debuginfo::WriterRelocate as gimli::write::writer::Writer>::write_initial_length
Line
Count
Source
303
70.2k
    fn write_initial_length(&mut self, format: Format) -> Result<InitialLengthOffset> {
304
70.2k
        if format == Format::Dwarf64 {
305
0
            self.write_u32(0xffff_ffff)?;
306
70.2k
        }
307
70.2k
        let offset = InitialLengthOffset(self.len());
308
70.2k
        self.write_udata(0, format.word_size())?;
309
70.2k
        Ok(offset)
310
70.2k
    }
311
312
    /// Write an initial length at the given offset according to the given DWARF format.
313
    ///
314
    /// `write_initial_length` must have previously returned the offset.
315
2.02M
    fn write_initial_length_at(
316
2.02M
        &mut self,
317
2.02M
        offset: InitialLengthOffset,
318
2.02M
        length: u64,
319
2.02M
        format: Format,
320
2.02M
    ) -> Result<()> {
321
2.02M
        self.write_udata_at(offset.0, length, format.word_size())
322
2.02M
    }
<gimli::write::endian_vec::EndianVec<gimli::endianity::RunTimeEndian> as gimli::write::writer::Writer>::write_initial_length_at
Line
Count
Source
315
1.95M
    fn write_initial_length_at(
316
1.95M
        &mut self,
317
1.95M
        offset: InitialLengthOffset,
318
1.95M
        length: u64,
319
1.95M
        format: Format,
320
1.95M
    ) -> Result<()> {
321
1.95M
        self.write_udata_at(offset.0, length, format.word_size())
322
1.95M
    }
<wasmtime_debug::write_debuginfo::WriterRelocate as gimli::write::writer::Writer>::write_initial_length_at
Line
Count
Source
315
70.2k
    fn write_initial_length_at(
316
70.2k
        &mut self,
317
70.2k
        offset: InitialLengthOffset,
318
70.2k
        length: u64,
319
70.2k
        format: Format,
320
70.2k
    ) -> Result<()> {
321
70.2k
        self.write_udata_at(offset.0, length, format.word_size())
322
70.2k
    }
323
}
324
325
/// The offset at which an initial length should be written.
326
0
#[derive(Debug, Clone, Copy)]
Unexecuted instantiation: <gimli::write::writer::InitialLengthOffset as core::fmt::Debug>::fmt
327
pub struct InitialLengthOffset(usize);
328
329
#[cfg(test)]
330
mod tests {
331
    use super::*;
332
    use crate::write;
333
    use crate::{BigEndian, LittleEndian};
334
    use std::{i64, u64};
335
336
    #[test]
337
    #[allow(clippy::cyclomatic_complexity)]
338
    fn test_writer() {
339
        let mut w = write::EndianVec::new(LittleEndian);
340
        w.write_address(Address::Constant(0x1122_3344), 4).unwrap();
341
        assert_eq!(w.slice(), &[0x44, 0x33, 0x22, 0x11]);
342
        assert_eq!(
343
            w.write_address(
344
                Address::Symbol {
345
                    symbol: 0,
346
                    addend: 0
347
                },
348
                4
349
            ),
350
            Err(Error::InvalidAddress)
351
        );
352
353
        let mut w = write::EndianVec::new(LittleEndian);
354
        w.write_offset(0x1122_3344, SectionId::DebugInfo, 4)
355
            .unwrap();
356
        assert_eq!(w.slice(), &[0x44, 0x33, 0x22, 0x11]);
357
        w.write_offset_at(1, 0x5566, SectionId::DebugInfo, 2)
358
            .unwrap();
359
        assert_eq!(w.slice(), &[0x44, 0x66, 0x55, 0x11]);
360
361
        let mut w = write::EndianVec::new(LittleEndian);
362
        w.write_u8(0x11).unwrap();
363
        w.write_u16(0x2233).unwrap();
364
        w.write_u32(0x4455_6677).unwrap();
365
        w.write_u64(0x8081_8283_8485_8687).unwrap();
366
        #[rustfmt::skip]
367
        assert_eq!(w.slice(), &[
368
            0x11,
369
            0x33, 0x22,
370
            0x77, 0x66, 0x55, 0x44,
371
            0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80,
372
        ]);
373
        w.write_u8_at(14, 0x11).unwrap();
374
        w.write_u16_at(12, 0x2233).unwrap();
375
        w.write_u32_at(8, 0x4455_6677).unwrap();
376
        w.write_u64_at(0, 0x8081_8283_8485_8687).unwrap();
377
        #[rustfmt::skip]
378
        assert_eq!(w.slice(), &[
379
            0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80,
380
            0x77, 0x66, 0x55, 0x44,
381
            0x33, 0x22,
382
            0x11,
383
        ]);
384
385
        let mut w = write::EndianVec::new(BigEndian);
386
        w.write_u8(0x11).unwrap();
387
        w.write_u16(0x2233).unwrap();
388
        w.write_u32(0x4455_6677).unwrap();
389
        w.write_u64(0x8081_8283_8485_8687).unwrap();
390
        #[rustfmt::skip]
391
        assert_eq!(w.slice(), &[
392
            0x11,
393
            0x22, 0x33,
394
            0x44, 0x55, 0x66, 0x77,
395
            0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
396
        ]);
397
        w.write_u8_at(14, 0x11).unwrap();
398
        w.write_u16_at(12, 0x2233).unwrap();
399
        w.write_u32_at(8, 0x4455_6677).unwrap();
400
        w.write_u64_at(0, 0x8081_8283_8485_8687).unwrap();
401
        #[rustfmt::skip]
402
        assert_eq!(w.slice(), &[
403
            0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
404
            0x44, 0x55, 0x66, 0x77,
405
            0x22, 0x33,
406
            0x11,
407
        ]);
408
409
        let mut w = write::EndianVec::new(LittleEndian);
410
        w.write_udata(0x11, 1).unwrap();
411
        w.write_udata(0x2233, 2).unwrap();
412
        w.write_udata(0x4455_6677, 4).unwrap();
413
        w.write_udata(0x8081_8283_8485_8687, 8).unwrap();
414
        #[rustfmt::skip]
415
        assert_eq!(w.slice(), &[
416
            0x11,
417
            0x33, 0x22,
418
            0x77, 0x66, 0x55, 0x44,
419
            0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80,
420
        ]);
421
        assert_eq!(w.write_udata(0x100, 1), Err(Error::ValueTooLarge));
422
        assert_eq!(w.write_udata(0x1_0000, 2), Err(Error::ValueTooLarge));
423
        assert_eq!(w.write_udata(0x1_0000_0000, 4), Err(Error::ValueTooLarge));
424
        assert_eq!(w.write_udata(0x00, 3), Err(Error::UnsupportedWordSize(3)));
425
        w.write_udata_at(14, 0x11, 1).unwrap();
426
        w.write_udata_at(12, 0x2233, 2).unwrap();
427
        w.write_udata_at(8, 0x4455_6677, 4).unwrap();
428
        w.write_udata_at(0, 0x8081_8283_8485_8687, 8).unwrap();
429
        #[rustfmt::skip]
430
        assert_eq!(w.slice(), &[
431
            0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80,
432
            0x77, 0x66, 0x55, 0x44,
433
            0x33, 0x22,
434
            0x11,
435
        ]);
436
        assert_eq!(w.write_udata_at(0, 0x100, 1), Err(Error::ValueTooLarge));
437
        assert_eq!(w.write_udata_at(0, 0x1_0000, 2), Err(Error::ValueTooLarge));
438
        assert_eq!(
439
            w.write_udata_at(0, 0x1_0000_0000, 4),
440
            Err(Error::ValueTooLarge)
441
        );
442
        assert_eq!(
443
            w.write_udata_at(0, 0x00, 3),
444
            Err(Error::UnsupportedWordSize(3))
445
        );
446
447
        let mut w = write::EndianVec::new(LittleEndian);
448
        w.write_uleb128(0).unwrap();
449
        assert_eq!(w.slice(), &[0]);
450
451
        let mut w = write::EndianVec::new(LittleEndian);
452
        w.write_uleb128(u64::MAX).unwrap();
453
        assert_eq!(
454
            w.slice(),
455
            &[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1]
456
        );
457
458
        let mut w = write::EndianVec::new(LittleEndian);
459
        w.write_sleb128(0).unwrap();
460
        assert_eq!(w.slice(), &[0]);
461
462
        let mut w = write::EndianVec::new(LittleEndian);
463
        w.write_sleb128(i64::MAX).unwrap();
464
        assert_eq!(
465
            w.slice(),
466
            &[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0]
467
        );
468
469
        let mut w = write::EndianVec::new(LittleEndian);
470
        w.write_sleb128(i64::MIN).unwrap();
471
        assert_eq!(
472
            w.slice(),
473
            &[0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7f]
474
        );
475
476
        let mut w = write::EndianVec::new(LittleEndian);
477
        let offset = w.write_initial_length(Format::Dwarf32).unwrap();
478
        assert_eq!(w.slice(), &[0, 0, 0, 0]);
479
        w.write_initial_length_at(offset, 0x1122_3344, Format::Dwarf32)
480
            .unwrap();
481
        assert_eq!(w.slice(), &[0x44, 0x33, 0x22, 0x11]);
482
        assert_eq!(
483
            w.write_initial_length_at(offset, 0x1_0000_0000, Format::Dwarf32),
484
            Err(Error::ValueTooLarge)
485
        );
486
487
        let mut w = write::EndianVec::new(LittleEndian);
488
        let offset = w.write_initial_length(Format::Dwarf64).unwrap();
489
        assert_eq!(w.slice(), &[0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0]);
490
        w.write_initial_length_at(offset, 0x1122_3344_5566_7788, Format::Dwarf64)
491
            .unwrap();
492
        assert_eq!(
493
            w.slice(),
494
            &[0xff, 0xff, 0xff, 0xff, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11]
495
        );
496
    }
497
}