2020-04-25 18:23:31 +02:00
|
|
|
use crate::prelude::*;
|
|
|
|
|
2020-05-01 19:21:29 +02:00
|
|
|
use cranelift_codegen::isa::{TargetIsa, unwind::UnwindInfo};
|
2020-04-25 18:23:31 +02:00
|
|
|
|
2020-05-01 19:21:29 +02:00
|
|
|
use gimli::write::{Address, CieId, EhFrame, FrameTable, Section};
|
2020-04-25 18:23:31 +02:00
|
|
|
|
2020-05-01 19:21:29 +02:00
|
|
|
use crate::backend::WriteDebugInfo;
|
|
|
|
|
|
|
|
pub(crate) struct UnwindContext<'tcx> {
|
|
|
|
tcx: TyCtxt<'tcx>,
|
|
|
|
frame_table: FrameTable,
|
|
|
|
cie_id: CieId,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'tcx> UnwindContext<'tcx> {
|
|
|
|
pub(crate) fn new(
|
|
|
|
tcx: TyCtxt<'tcx>,
|
|
|
|
module: &mut Module<impl Backend>,
|
|
|
|
) -> Self {
|
|
|
|
let mut frame_table = FrameTable::default();
|
|
|
|
let cie = module.isa().create_systemv_cie().expect("SystemV unwind info CIE");
|
|
|
|
|
|
|
|
let cie_id = frame_table.add_cie(cie);
|
|
|
|
|
|
|
|
UnwindContext {
|
|
|
|
tcx,
|
|
|
|
frame_table,
|
|
|
|
cie_id,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn add_function(&mut self, func_id: FuncId, context: &Context, isa: &dyn TargetIsa) {
|
2020-04-25 18:23:31 +02:00
|
|
|
let unwind_info = if let Some(unwind_info) = context.create_unwind_info(isa).unwrap() {
|
|
|
|
unwind_info
|
|
|
|
} else {
|
|
|
|
return;
|
|
|
|
};
|
|
|
|
|
|
|
|
match unwind_info {
|
|
|
|
UnwindInfo::SystemV(unwind_info) => {
|
2020-05-01 19:21:29 +02:00
|
|
|
self.frame_table.add_fde(self.cie_id, unwind_info.to_fde(Address::Symbol {
|
|
|
|
symbol: func_id.as_u32() as usize,
|
2020-04-25 18:23:31 +02:00
|
|
|
addend: 0,
|
|
|
|
}));
|
|
|
|
},
|
|
|
|
UnwindInfo::WindowsX64(_) => {
|
|
|
|
// FIXME implement this
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-05-01 19:21:29 +02:00
|
|
|
|
|
|
|
pub(crate) fn emit<P: WriteDebugInfo>(self, product: &mut P) {
|
|
|
|
let mut eh_frame = EhFrame::from(super::emit::WriterRelocate::new(super::target_endian(self.tcx)));
|
|
|
|
self.frame_table.write_eh_frame(&mut eh_frame).unwrap();
|
|
|
|
|
|
|
|
if !eh_frame.0.writer.slice().is_empty() {
|
|
|
|
let id = eh_frame.id();
|
|
|
|
let section_id = product.add_debug_section(id, eh_frame.0.writer.into_vec());
|
|
|
|
let mut section_map = FxHashMap::default();
|
|
|
|
section_map.insert(id, section_id);
|
|
|
|
|
|
|
|
for reloc in &eh_frame.0.relocs {
|
|
|
|
product.add_debug_reloc(§ion_map, §ion_id, reloc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-04-25 18:23:31 +02:00
|
|
|
}
|