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

Method write_systemv_unwind_info

crates/cranelift/src/obj.rs:514–597  ·  view source on GitHub ↗

This function appends a nonstandard section to the object which is only used during `CodeMemory::publish`. This will generate a `.eh_frame` section, but not one that can be naively loaded. The goal of this section is that we can create the section once here and never again does it need to change. To describe dynamically loaded functions though each individual FDE needs to talk about the function'

(
        &self,
        compiler: &dyn Compiler,
        obj: &mut Object<'_>,
        section_id: SectionId,
        text_section_size: u64,
    )

Source from the content-addressed store, hash-verified

512 /// such as being purely read-only instead of read/execute like the code
513 /// bits.
514 fn write_systemv_unwind_info(
515 &self,
516 compiler: &dyn Compiler,
517 obj: &mut Object<'_>,
518 section_id: SectionId,
519 text_section_size: u64,
520 ) {
521 let mut cie = match compiler.create_systemv_cie() {
522 Some(cie) => cie,
523 None => return,
524 };
525 let mut table = FrameTable::default();
526 cie.fde_address_encoding = gimli::constants::DW_EH_PE_pcrel;
527 let cie_id = table.add_cie(cie);
528
529 for (text_section_off, unwind_info) in self.systemv_unwind_info.iter() {
530 let backwards_off = text_section_size - text_section_off;
531 let actual_offset = -i64::try_from(backwards_off).unwrap();
532 // Note that gimli wants an unsigned 64-bit integer here, but
533 // unwinders just use this constant for a relative addition with the
534 // address of the FDE, which means that the sign doesn't actually
535 // matter.
536 let fde = unwind_info.to_fde(Address::Constant(actual_offset.cast_unsigned()));
537 table.add_fde(cie_id, fde);
538 }
539 let endian = match compiler.triple().endianness().unwrap() {
540 target_lexicon::Endianness::Little => RunTimeEndian::Little,
541 target_lexicon::Endianness::Big => RunTimeEndian::Big,
542 };
543 let mut eh_frame = EhFrame(MyVec(EndianVec::new(endian)));
544 table.write_eh_frame(&mut eh_frame).unwrap();
545
546 // Some unwinding implementations expect a terminating "empty" length so
547 // a 0 is written at the end of the table for those implementations.
548 let mut endian_vec = (eh_frame.0).0;
549 endian_vec.write_u32(0).unwrap();
550 obj.append_section_data(section_id, endian_vec.slice(), 1);
551
552 use gimli::constants;
553 use gimli::write::Error;
554
555 struct MyVec(EndianVec<RunTimeEndian>);
556
557 impl Writer for MyVec {
558 type Endian = RunTimeEndian;
559
560 fn endian(&self) -> RunTimeEndian {
561 self.0.endian()
562 }
563
564 fn len(&self) -> usize {
565 self.0.len()
566 }
567
568 fn write(&mut self, buf: &[u8]) -> Result<(), Error> {
569 self.0.write(buf)
570 }
571

Callers 1

append_sectionMethod · 0.80

Calls 11

MyVecClass · 0.85
to_fdeMethod · 0.80
ConstantClass · 0.50
newFunction · 0.50
create_systemv_cieMethod · 0.45
iterMethod · 0.45
unwrapMethod · 0.45
endiannessMethod · 0.45
tripleMethod · 0.45
write_u32Method · 0.45
sliceMethod · 0.45

Tested by

no test coverage detected