Serialize all collected FDEs into an `.eh_frame` section on `object`. Returns without writing anything if no FDE was ever added (e.g. when the user enabled unwind info on a target that does not produce System V frames). The pointer-width unwrap is safe because [`ObjectBuilder`] has already rejected unknown architectures during construction. [`ObjectBuilder`]: crate::ObjectBuilder
(self, object: &mut Object<'static>, isa: &dyn TargetIsa)
| 87 | /// |
| 88 | /// [`ObjectBuilder`]: crate::ObjectBuilder |
| 89 | pub(crate) fn finish(self, object: &mut Object<'static>, isa: &dyn TargetIsa) -> Result<()> { |
| 90 | let UnwindBuilder { |
| 91 | section, |
| 92 | frame_table, |
| 93 | cie_id, |
| 94 | symbols, |
| 95 | } = self; |
| 96 | if cie_id.is_none() { |
| 97 | return Ok(()); |
| 98 | } |
| 99 | let mut eh_frame = EhFrame(section); |
| 100 | frame_table |
| 101 | .write_eh_frame(&mut eh_frame) |
| 102 | .map_err(|err| anyhow!("failed to write .eh_frame: {err}"))?; |
| 103 | let EhFrame(EhFrameSection { |
| 104 | writer, |
| 105 | relocations, |
| 106 | }) = eh_frame; |
| 107 | |
| 108 | let section_id = object.section_id(StandardSection::EhFrame); |
| 109 | let alignment = u64::from(isa.triple().pointer_width().unwrap().bytes()); |
| 110 | object.append_section_data(section_id, &writer.into_vec(), alignment); |
| 111 | |
| 112 | let format = object.format(); |
| 113 | for reloc in relocations { |
| 114 | let symbol_id = match reloc.target { |
| 115 | RelocationTarget::Symbol(index) => symbols[index], |
| 116 | // gimli's writer only emits section-relative relocations for |
| 117 | // DWARF debug sections, never for `.eh_frame`. Skip defensively. |
| 118 | RelocationTarget::Section(_) => continue, |
| 119 | }; |
| 120 | let flags = translate_eh_pe(reloc.eh_pe, reloc.size, format)?; |
| 121 | object |
| 122 | .add_relocation( |
| 123 | section_id, |
| 124 | ObjectRelocation { |
| 125 | offset: reloc.offset as u64, |
| 126 | symbol: symbol_id, |
| 127 | addend: reloc.addend, |
| 128 | flags, |
| 129 | }, |
| 130 | ) |
| 131 | .map_err(|err| anyhow!("failed to record .eh_frame relocation: {err}"))?; |
| 132 | } |
| 133 | Ok(()) |
| 134 | } |
| 135 | } |
| 136 | |
| 137 | struct EhFrameSection { |