MCPcopy Create free account
hub / github.com/bytecodealliance/wasmtime / push

Method push

crates/cranelift/src/obj.rs:267–369  ·  view source on GitHub ↗

Pushes the unwind information for a function into this builder. The function being described must be located at `function_offset` within the text section itself, and the function's size is specified by `function_len`. The `info` should come from Cranelift. and is handled here depending on its flavor.

(&mut self, function_offset: u64, function_len: u64, info: &'a UnwindInfo)

Source from the content-addressed store, hash-verified

265 /// The `info` should come from Cranelift. and is handled here depending on
266 /// its flavor.
267 fn push(&mut self, function_offset: u64, function_len: u64, info: &'a UnwindInfo) {
268 match info {
269 // Windows unwind information is stored in two locations:
270 //
271 // * First is the actual unwinding information which is stored
272 // in the `.xdata` section. This is where `info`'s emitted
273 // information will go into.
274 // * Second are pointers to connect all this unwind information,
275 // stored in the `.pdata` section. The `.pdata` section is an
276 // array of `RUNTIME_FUNCTION` structures.
277 //
278 // Due to how these will be loaded at runtime the `.pdata` isn't
279 // actually assembled byte-wise here. Instead that's deferred to
280 // happen later during `write_windows_unwind_info` which will apply
281 // a further offset to `unwind_address`.
282 //
283 // FIXME: in theory we could "intern" the `unwind_info` value
284 // here within the `.xdata` section. Most of our unwind
285 // information for functions is probably pretty similar in which
286 // case the `.xdata` could be quite small and `.pdata` could
287 // have multiple functions point to the same unwinding
288 // information.
289 UnwindInfo::WindowsX64(info) => {
290 let unwind_size = info.emit_size();
291 let mut unwind_info = vec![0; unwind_size];
292 info.emit(&mut unwind_info);
293
294 // `.xdata` entries are always 4-byte aligned
295 while self.windows_xdata.len() % 4 != 0 {
296 self.windows_xdata.push(0x00);
297 }
298 let unwind_address = self.windows_xdata.len();
299 self.windows_xdata.extend_from_slice(&unwind_info);
300
301 // Record a `RUNTIME_FUNCTION` which this will point to.
302 self.windows_pdata.push(RUNTIME_FUNCTION {
303 begin: u32::try_from(function_offset).unwrap(),
304 end: u32::try_from(function_offset + function_len).unwrap(),
305 unwind_address: u32::try_from(unwind_address).unwrap(),
306 });
307 }
308
309 // See https://learn.microsoft.com/en-us/cpp/build/arm64-exception-handling
310 UnwindInfo::WindowsArm64(info) => {
311 let code_words = info.code_words();
312 let mut unwind_codes = vec![0; (code_words * 4) as usize];
313 info.emit(&mut unwind_codes);
314
315 // `.xdata` entries are always 4-byte aligned
316 while self.windows_xdata.len() % 4 != 0 {
317 self.windows_xdata.push(0x00);
318 }
319
320 // First word:
321 // 0-17: Function Length
322 // 18-19: Version (must be 0)
323 // 20: X bit (is exception data present?)
324 // 21: E bit (has single packed epilogue?)

Callers 1

append_funcMethod · 0.45

Calls 6

fromFunction · 0.85
emit_sizeMethod · 0.80
code_wordsMethod · 0.80
emitMethod · 0.45
lenMethod · 0.45
unwrapMethod · 0.45

Tested by

no test coverage detected