Merge pull request #982 from bjorn3/backtrace_support
Implement .eh_frame writing
This commit is contained in:
commit
7dbbfe668f
@ -9,7 +9,7 @@ crate-type = ["dylib"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# These have to be in sync with each other
|
# 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-frontend = { git = "https://github.com/bytecodealliance/wasmtime/" }
|
||||||
cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime/" }
|
cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime/" }
|
||||||
cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime/" }
|
cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime/" }
|
||||||
|
@ -39,7 +39,7 @@ impl WriteMetadata for object::write::Object {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) trait WriteDebugInfo {
|
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_section(&mut self, name: SectionId, data: Vec<u8>) -> Self::SectionId;
|
||||||
fn add_debug_reloc(
|
fn add_debug_reloc(
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use rustc_data_structures::fx::FxHashMap;
|
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 gimli::{RunTimeEndian, SectionId};
|
||||||
|
|
||||||
use crate::backend::WriteDebugInfo;
|
use crate::backend::WriteDebugInfo;
|
||||||
@ -20,6 +20,9 @@ impl DebugContext<'_> {
|
|||||||
let mut sections = Sections::new(WriterRelocate::new(self));
|
let mut sections = Sections::new(WriterRelocate::new(self));
|
||||||
self.dwarf.write(&mut sections).unwrap();
|
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 mut section_map = FxHashMap::default();
|
||||||
let _: Result<()> = sections.for_each_mut(|id, section| {
|
let _: Result<()> = sections.for_each_mut(|id, section| {
|
||||||
if !section.writer.slice().is_empty() {
|
if !section.writer.slice().is_empty() {
|
||||||
@ -37,6 +40,16 @@ impl DebugContext<'_> {
|
|||||||
}
|
}
|
||||||
Ok(())
|
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 emit;
|
||||||
mod line_info;
|
mod line_info;
|
||||||
|
mod unwind;
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
@ -10,8 +11,8 @@ use cranelift_codegen::isa::TargetIsa;
|
|||||||
use cranelift_codegen::ValueLocRange;
|
use cranelift_codegen::ValueLocRange;
|
||||||
|
|
||||||
use gimli::write::{
|
use gimli::write::{
|
||||||
self, Address, AttributeValue, DwarfUnit, Expression, LineProgram, LineString, Location,
|
self, Address, AttributeValue, CieId, DwarfUnit, Expression, FrameTable, LineProgram,
|
||||||
LocationList, Range, RangeList, UnitEntryId, Writer,
|
LineString, Location, LocationList, Range, RangeList, UnitEntryId, Writer,
|
||||||
};
|
};
|
||||||
use gimli::{Encoding, Format, LineEncoding, RunTimeEndian, X86_64};
|
use gimli::{Encoding, Format, LineEncoding, RunTimeEndian, X86_64};
|
||||||
|
|
||||||
@ -34,13 +35,15 @@ pub(crate) struct DebugContext<'tcx> {
|
|||||||
|
|
||||||
dwarf: DwarfUnit,
|
dwarf: DwarfUnit,
|
||||||
unit_range_list: RangeList,
|
unit_range_list: RangeList,
|
||||||
|
frame_table: FrameTable,
|
||||||
|
|
||||||
|
cie: CieId,
|
||||||
clif_types: FxHashMap<Type, UnitEntryId>,
|
clif_types: FxHashMap<Type, UnitEntryId>,
|
||||||
types: FxHashMap<Ty<'tcx>, UnitEntryId>,
|
types: FxHashMap<Ty<'tcx>, UnitEntryId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> DebugContext<'tcx> {
|
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 {
|
let encoding = Encoding {
|
||||||
format: Format::Dwarf32,
|
format: Format::Dwarf32,
|
||||||
// TODO: this should be configurable
|
// TODO: this should be configurable
|
||||||
@ -53,7 +56,7 @@ impl<'tcx> DebugContext<'tcx> {
|
|||||||
// support it.
|
// support it.
|
||||||
4
|
4
|
||||||
},
|
},
|
||||||
address_size,
|
address_size: isa.frontend_config().pointer_bytes(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut dwarf = DwarfUnit::new(encoding);
|
let mut dwarf = DwarfUnit::new(encoding);
|
||||||
@ -108,6 +111,9 @@ impl<'tcx> DebugContext<'tcx> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut frame_table = FrameTable::default();
|
||||||
|
let cie = frame_table.add_cie(isa.create_systemv_cie().expect("SystemV unwind info CIE"));
|
||||||
|
|
||||||
DebugContext {
|
DebugContext {
|
||||||
tcx,
|
tcx,
|
||||||
|
|
||||||
@ -116,7 +122,9 @@ impl<'tcx> DebugContext<'tcx> {
|
|||||||
|
|
||||||
dwarf,
|
dwarf,
|
||||||
unit_range_list: RangeList(Vec::new()),
|
unit_range_list: RangeList(Vec::new()),
|
||||||
|
frame_table,
|
||||||
|
|
||||||
|
cie,
|
||||||
clif_types: FxHashMap::default(),
|
clif_types: FxHashMap::default(),
|
||||||
types: FxHashMap::default(),
|
types: FxHashMap::default(),
|
||||||
}
|
}
|
||||||
@ -312,6 +320,8 @@ impl<'a, 'tcx> FunctionDebugContext<'a, 'tcx> {
|
|||||||
source_info_set: &indexmap::IndexSet<SourceInfo>,
|
source_info_set: &indexmap::IndexSet<SourceInfo>,
|
||||||
local_map: FxHashMap<mir::Local, CPlace<'tcx>>,
|
local_map: FxHashMap<mir::Local, CPlace<'tcx>>,
|
||||||
) {
|
) {
|
||||||
|
self.create_unwind_info(context, isa);
|
||||||
|
|
||||||
let end = self.create_debug_lines(context, isa, source_info_set);
|
let end = self.create_debug_lines(context, isa, source_info_set);
|
||||||
|
|
||||||
self.debug_context
|
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 mut debug = if tcx.sess.opts.debuginfo != DebugInfo::None {
|
||||||
let debug = DebugContext::new(
|
let debug = DebugContext::new(
|
||||||
tcx,
|
tcx,
|
||||||
module.target_config().pointer_type().bytes() as u8,
|
module.isa(),
|
||||||
);
|
);
|
||||||
Some(debug)
|
Some(debug)
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user