Implement .eh_frame writing
This commit is contained in:
parent
9d6f65ea14
commit
e7661d49c3
@ -9,7 +9,7 @@ crate-type = ["dylib"]
|
||||
|
||||
[dependencies]
|
||||
# These have to be in sync with each other
|
||||
cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime/" }
|
||||
cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime/", features = ["unwind"] }
|
||||
cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime/" }
|
||||
cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime/" }
|
||||
cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime/" }
|
||||
|
@ -39,7 +39,7 @@ fn add_rustc_section(&mut self, symbol_name: String, data: Vec<u8>, _is_like_osx
|
||||
}
|
||||
|
||||
pub(crate) trait WriteDebugInfo {
|
||||
type SectionId;
|
||||
type SectionId: Copy;
|
||||
|
||||
fn add_debug_section(&mut self, name: SectionId, data: Vec<u8>) -> Self::SectionId;
|
||||
fn add_debug_reloc(
|
||||
|
@ -1,6 +1,6 @@
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
|
||||
use gimli::write::{Address, AttributeValue, EndianVec, Result, Sections, Writer};
|
||||
use gimli::write::{Address, AttributeValue, EhFrame, EndianVec, Result, Sections, Writer, Section};
|
||||
use gimli::{RunTimeEndian, SectionId};
|
||||
|
||||
use crate::backend::WriteDebugInfo;
|
||||
@ -20,6 +20,9 @@ pub(crate) fn emit<P: WriteDebugInfo>(&mut self, product: &mut P) {
|
||||
let mut sections = Sections::new(WriterRelocate::new(self));
|
||||
self.dwarf.write(&mut sections).unwrap();
|
||||
|
||||
let mut eh_frame = EhFrame::from(WriterRelocate::new(self));
|
||||
self.frame_table.write_eh_frame(&mut eh_frame).unwrap();
|
||||
|
||||
let mut section_map = FxHashMap::default();
|
||||
let _: Result<()> = sections.for_each_mut(|id, section| {
|
||||
if !section.writer.slice().is_empty() {
|
||||
@ -37,6 +40,16 @@ pub(crate) fn emit<P: WriteDebugInfo>(&mut self, product: &mut P) {
|
||||
}
|
||||
Ok(())
|
||||
});
|
||||
|
||||
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());
|
||||
section_map.insert(id, section_id);
|
||||
|
||||
for reloc in &eh_frame.0.relocs {
|
||||
product.add_debug_reloc(§ion_map, &self.symbols, §ion_id, reloc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
mod emit;
|
||||
mod line_info;
|
||||
mod unwind;
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
@ -10,8 +11,8 @@
|
||||
use cranelift_codegen::ValueLocRange;
|
||||
|
||||
use gimli::write::{
|
||||
self, Address, AttributeValue, DwarfUnit, Expression, LineProgram, LineString, Location,
|
||||
LocationList, Range, RangeList, UnitEntryId, Writer,
|
||||
self, Address, AttributeValue, CieId, DwarfUnit, Expression, FrameTable, LineProgram,
|
||||
LineString, Location, LocationList, Range, RangeList, UnitEntryId, Writer,
|
||||
};
|
||||
use gimli::{Encoding, Format, LineEncoding, RunTimeEndian, X86_64};
|
||||
|
||||
@ -34,13 +35,15 @@ pub(crate) struct DebugContext<'tcx> {
|
||||
|
||||
dwarf: DwarfUnit,
|
||||
unit_range_list: RangeList,
|
||||
frame_table: FrameTable,
|
||||
|
||||
cie: CieId,
|
||||
clif_types: FxHashMap<Type, UnitEntryId>,
|
||||
types: FxHashMap<Ty<'tcx>, UnitEntryId>,
|
||||
}
|
||||
|
||||
impl<'tcx> DebugContext<'tcx> {
|
||||
pub(crate) fn new(tcx: TyCtxt<'tcx>, address_size: u8) -> Self {
|
||||
pub(crate) fn new(tcx: TyCtxt<'tcx>, isa: &dyn TargetIsa) -> Self {
|
||||
let encoding = Encoding {
|
||||
format: Format::Dwarf32,
|
||||
// TODO: this should be configurable
|
||||
@ -53,7 +56,7 @@ pub(crate) fn new(tcx: TyCtxt<'tcx>, address_size: u8) -> Self {
|
||||
// support it.
|
||||
4
|
||||
},
|
||||
address_size,
|
||||
address_size: isa.frontend_config().pointer_bytes(),
|
||||
};
|
||||
|
||||
let mut dwarf = DwarfUnit::new(encoding);
|
||||
@ -108,6 +111,9 @@ pub(crate) fn new(tcx: TyCtxt<'tcx>, address_size: u8) -> Self {
|
||||
);
|
||||
}
|
||||
|
||||
let mut frame_table = FrameTable::default();
|
||||
let cie = frame_table.add_cie(isa.create_systemv_cie().expect("SystemV unwind info CIE"));
|
||||
|
||||
DebugContext {
|
||||
tcx,
|
||||
|
||||
@ -116,7 +122,9 @@ pub(crate) fn new(tcx: TyCtxt<'tcx>, address_size: u8) -> Self {
|
||||
|
||||
dwarf,
|
||||
unit_range_list: RangeList(Vec::new()),
|
||||
frame_table,
|
||||
|
||||
cie,
|
||||
clif_types: FxHashMap::default(),
|
||||
types: FxHashMap::default(),
|
||||
}
|
||||
@ -312,6 +320,8 @@ pub(crate) fn define(
|
||||
source_info_set: &indexmap::IndexSet<SourceInfo>,
|
||||
local_map: FxHashMap<mir::Local, CPlace<'tcx>>,
|
||||
) {
|
||||
self.create_unwind_info(context, isa);
|
||||
|
||||
let end = self.create_debug_lines(context, isa, source_info_set);
|
||||
|
||||
self.debug_context
|
||||
|
31
src/debuginfo/unwind.rs
Normal file
31
src/debuginfo/unwind.rs
Normal file
@ -0,0 +1,31 @@
|
||||
use crate::prelude::*;
|
||||
|
||||
use cranelift_codegen::isa::unwind::UnwindInfo;
|
||||
|
||||
use gimli::write::Address;
|
||||
|
||||
impl<'a, 'tcx> FunctionDebugContext<'a, 'tcx> {
|
||||
pub(super) fn create_unwind_info(
|
||||
&mut self,
|
||||
context: &Context,
|
||||
isa: &dyn cranelift_codegen::isa::TargetIsa,
|
||||
) {
|
||||
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) => {
|
||||
self.debug_context.frame_table.add_fde(self.debug_context.cie, unwind_info.to_fde(Address::Symbol {
|
||||
symbol: self.symbol,
|
||||
addend: 0,
|
||||
}));
|
||||
},
|
||||
UnwindInfo::WindowsX64(_) => {
|
||||
// FIXME implement this
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -120,7 +120,7 @@ fn module_codegen(tcx: TyCtxt<'_>, cgu_name: rustc_span::Symbol) -> ModuleCodege
|
||||
let mut debug = if tcx.sess.opts.debuginfo != DebugInfo::None {
|
||||
let debug = DebugContext::new(
|
||||
tcx,
|
||||
module.target_config().pointer_type().bytes() as u8,
|
||||
module.isa(),
|
||||
);
|
||||
Some(debug)
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user