Always emit .eh_frame section
This commit is contained in:
parent
485e52e153
commit
4da6488d95
@ -1,4 +1,4 @@
|
||||
use std::convert::TryFrom;
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_session::Session;
|
||||
@ -45,7 +45,6 @@ pub(crate) trait WriteDebugInfo {
|
||||
fn add_debug_reloc(
|
||||
&mut self,
|
||||
section_map: &FxHashMap<SectionId, Self::SectionId>,
|
||||
symbol_map: &indexmap::IndexMap<FuncId, String>,
|
||||
from: &Self::SectionId,
|
||||
reloc: &DebugReloc,
|
||||
);
|
||||
@ -75,7 +74,6 @@ impl WriteDebugInfo for ObjectProduct {
|
||||
fn add_debug_reloc(
|
||||
&mut self,
|
||||
section_map: &FxHashMap<SectionId, Self::SectionId>,
|
||||
symbol_map: &indexmap::IndexMap<FuncId, String>,
|
||||
from: &Self::SectionId,
|
||||
reloc: &DebugReloc,
|
||||
) {
|
||||
@ -84,7 +82,7 @@ impl WriteDebugInfo for ObjectProduct {
|
||||
(section_map.get(&id).unwrap().1, 0)
|
||||
}
|
||||
DebugRelocName::Symbol(id) => {
|
||||
let symbol_id = self.function_symbol(*symbol_map.get_index(id).unwrap().0);
|
||||
let symbol_id = self.function_symbol(FuncId::from_u32(id.try_into().unwrap()));
|
||||
self.object.symbol_section_and_offset(symbol_id).expect("Debug reloc for undef sym???")
|
||||
}
|
||||
};
|
||||
|
@ -124,10 +124,12 @@ pub(crate) fn trans_fn<'clif, 'tcx, B: Backend + 'static>(
|
||||
|
||||
// Define debuginfo for function
|
||||
let isa = cx.module.isa();
|
||||
let unwind_context = &mut cx.unwind_context;
|
||||
tcx.sess.time("generate debug info", || {
|
||||
debug_context
|
||||
.as_mut()
|
||||
.map(|x| x.define(context, isa, &source_info_set, local_map));
|
||||
unwind_context.add_function(func_id, &context, isa);
|
||||
});
|
||||
|
||||
// Clear context to make it usable for the next function
|
||||
|
@ -1,6 +1,6 @@
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
|
||||
use gimli::write::{Address, AttributeValue, EhFrame, EndianVec, Result, Sections, Writer, Section};
|
||||
use gimli::write::{Address, AttributeValue, EndianVec, Result, Sections, Writer};
|
||||
use gimli::{RunTimeEndian, SectionId};
|
||||
|
||||
use crate::backend::WriteDebugInfo;
|
||||
@ -17,12 +17,9 @@ impl DebugContext<'_> {
|
||||
AttributeValue::RangeListRef(unit_range_list_id),
|
||||
);
|
||||
|
||||
let mut sections = Sections::new(WriterRelocate::new(self));
|
||||
let mut sections = Sections::new(WriterRelocate::new(self.endian));
|
||||
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() {
|
||||
@ -35,21 +32,11 @@ impl DebugContext<'_> {
|
||||
let _: Result<()> = sections.for_each(|id, section| {
|
||||
if let Some(section_id) = section_map.get(&id) {
|
||||
for reloc in §ion.relocs {
|
||||
product.add_debug_reloc(§ion_map, &self.symbols, section_id, reloc);
|
||||
product.add_debug_reloc(§ion_map, section_id, reloc);
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,16 +55,16 @@ pub(crate) enum DebugRelocName {
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct WriterRelocate {
|
||||
relocs: Vec<DebugReloc>,
|
||||
writer: EndianVec<RunTimeEndian>,
|
||||
pub(super) struct WriterRelocate {
|
||||
pub(super) relocs: Vec<DebugReloc>,
|
||||
pub(super) writer: EndianVec<RunTimeEndian>,
|
||||
}
|
||||
|
||||
impl WriterRelocate {
|
||||
fn new(ctx: &DebugContext<'_>) -> Self {
|
||||
pub(super) fn new(endian: RunTimeEndian) -> Self {
|
||||
WriterRelocate {
|
||||
relocs: Vec::new(),
|
||||
writer: EndianVec::new(ctx.endian),
|
||||
writer: EndianVec::new(endian),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,12 +11,13 @@ use cranelift_codegen::isa::TargetIsa;
|
||||
use cranelift_codegen::ValueLocRange;
|
||||
|
||||
use gimli::write::{
|
||||
self, Address, AttributeValue, CieId, DwarfUnit, Expression, FrameTable, LineProgram,
|
||||
self, Address, AttributeValue, DwarfUnit, Expression, LineProgram,
|
||||
LineString, Location, LocationList, Range, RangeList, UnitEntryId, Writer,
|
||||
};
|
||||
use gimli::{Encoding, Format, LineEncoding, RunTimeEndian, X86_64};
|
||||
|
||||
pub(crate) use emit::{DebugReloc, DebugRelocName};
|
||||
pub(crate) use unwind::UnwindContext;
|
||||
|
||||
fn target_endian(tcx: TyCtxt<'_>) -> RunTimeEndian {
|
||||
use rustc_target::abi::Endian;
|
||||
@ -31,13 +32,10 @@ pub(crate) struct DebugContext<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
|
||||
endian: RunTimeEndian,
|
||||
symbols: indexmap::IndexMap<FuncId, String>,
|
||||
|
||||
dwarf: DwarfUnit,
|
||||
unit_range_list: RangeList,
|
||||
frame_table: FrameTable,
|
||||
|
||||
cie: CieId,
|
||||
clif_types: FxHashMap<Type, UnitEntryId>,
|
||||
types: FxHashMap<Ty<'tcx>, UnitEntryId>,
|
||||
}
|
||||
@ -111,20 +109,14 @@ 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 {
|
||||
tcx,
|
||||
|
||||
endian: target_endian(tcx),
|
||||
symbols: indexmap::IndexMap::new(),
|
||||
|
||||
dwarf,
|
||||
unit_range_list: RangeList(Vec::new()),
|
||||
frame_table,
|
||||
|
||||
cie,
|
||||
clif_types: FxHashMap::default(),
|
||||
types: FxHashMap::default(),
|
||||
}
|
||||
@ -267,8 +259,6 @@ impl<'a, 'tcx> FunctionDebugContext<'a, 'tcx> {
|
||||
) -> Self {
|
||||
let mir = debug_context.tcx.instance_mir(instance.def);
|
||||
|
||||
let (symbol, _) = debug_context.symbols.insert_full(func_id, name.to_string());
|
||||
|
||||
// FIXME: add to appropriate scope intead of root
|
||||
let scope = debug_context.dwarf.unit.root();
|
||||
|
||||
@ -291,7 +281,7 @@ impl<'a, 'tcx> FunctionDebugContext<'a, 'tcx> {
|
||||
FunctionDebugContext {
|
||||
debug_context,
|
||||
entry_id,
|
||||
symbol,
|
||||
symbol: func_id.as_u32() as usize,
|
||||
instance,
|
||||
mir,
|
||||
}
|
||||
@ -320,8 +310,6 @@ impl<'a, 'tcx> FunctionDebugContext<'a, 'tcx> {
|
||||
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
|
||||
|
@ -1,15 +1,35 @@
|
||||
use crate::prelude::*;
|
||||
|
||||
use cranelift_codegen::isa::unwind::UnwindInfo;
|
||||
use cranelift_codegen::isa::{TargetIsa, unwind::UnwindInfo};
|
||||
|
||||
use gimli::write::Address;
|
||||
use gimli::write::{Address, CieId, EhFrame, FrameTable, Section};
|
||||
|
||||
impl<'a, 'tcx> FunctionDebugContext<'a, 'tcx> {
|
||||
pub(super) fn create_unwind_info(
|
||||
&mut self,
|
||||
context: &Context,
|
||||
isa: &dyn cranelift_codegen::isa::TargetIsa,
|
||||
) {
|
||||
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) {
|
||||
let unwind_info = if let Some(unwind_info) = context.create_unwind_info(isa).unwrap() {
|
||||
unwind_info
|
||||
} else {
|
||||
@ -18,8 +38,8 @@ impl<'a, 'tcx> FunctionDebugContext<'a, 'tcx> {
|
||||
|
||||
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,
|
||||
self.frame_table.add_fde(self.cie_id, unwind_info.to_fde(Address::Symbol {
|
||||
symbol: func_id.as_u32() as usize,
|
||||
addend: 0,
|
||||
}));
|
||||
},
|
||||
@ -28,4 +48,20 @@ impl<'a, 'tcx> FunctionDebugContext<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ fn emit_module<B: Backend>(
|
||||
kind: ModuleKind,
|
||||
mut module: Module<B>,
|
||||
debug: Option<DebugContext<'_>>,
|
||||
unwind_context: UnwindContext<'_>,
|
||||
) -> ModuleCodegenResult
|
||||
where B::Product: Emit + WriteDebugInfo,
|
||||
{
|
||||
@ -42,6 +43,8 @@ fn emit_module<B: Backend>(
|
||||
debug.emit(&mut product);
|
||||
}
|
||||
|
||||
unwind_context.emit(&mut product);
|
||||
|
||||
let tmp_file = tcx
|
||||
.output_filenames(LOCAL_CRATE)
|
||||
.temp_path(OutputType::Object, Some(&name));
|
||||
@ -125,7 +128,9 @@ fn module_codegen(tcx: TyCtxt<'_>, cgu_name: rustc_span::Symbol) -> ModuleCodege
|
||||
None
|
||||
};
|
||||
|
||||
super::codegen_mono_items(tcx, &mut module, debug.as_mut(), mono_items);
|
||||
let mut unwind_context = UnwindContext::new(tcx, &mut module);
|
||||
|
||||
super::codegen_mono_items(tcx, &mut module, debug.as_mut(), &mut unwind_context, mono_items);
|
||||
crate::main_shim::maybe_create_entry_wrapper(tcx, &mut module);
|
||||
|
||||
emit_module(
|
||||
@ -134,6 +139,7 @@ fn module_codegen(tcx: TyCtxt<'_>, cgu_name: rustc_span::Symbol) -> ModuleCodege
|
||||
ModuleKind::Regular,
|
||||
module,
|
||||
debug,
|
||||
unwind_context,
|
||||
)
|
||||
}
|
||||
|
||||
@ -190,12 +196,16 @@ pub(super) fn run_aot(
|
||||
let created_alloc_shim = crate::allocator::codegen(tcx, &mut allocator_module);
|
||||
|
||||
let allocator_module = if created_alloc_shim {
|
||||
// FIXME create .eh_frame for allocator shim
|
||||
let unwind_context = UnwindContext::new(tcx, &mut allocator_module);
|
||||
|
||||
let ModuleCodegenResult(module, work_product) = emit_module(
|
||||
tcx,
|
||||
"allocator_shim".to_string(),
|
||||
ModuleKind::Allocator,
|
||||
allocator_module,
|
||||
None,
|
||||
unwind_context,
|
||||
);
|
||||
if let Some((id, product)) = work_product {
|
||||
work_products.insert(id, product);
|
||||
|
@ -52,8 +52,11 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>) -> ! {
|
||||
.into_iter()
|
||||
.collect::<Vec<(_, (_, _))>>();
|
||||
|
||||
// FIXME register with unwind runtime
|
||||
let mut unwind_context = UnwindContext::new(tcx, &mut jit_module);
|
||||
|
||||
super::time(tcx, "codegen mono items", || {
|
||||
super::codegen_mono_items(tcx, &mut jit_module, None, mono_items);
|
||||
super::codegen_mono_items(tcx, &mut jit_module, None, &mut unwind_context, mono_items);
|
||||
});
|
||||
crate::main_shim::maybe_create_entry_wrapper(tcx, &mut jit_module);
|
||||
crate::allocator::codegen(tcx, &mut jit_module);
|
||||
|
@ -33,9 +33,10 @@ fn codegen_mono_items<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
module: &mut Module<impl Backend + 'static>,
|
||||
debug_context: Option<&mut DebugContext<'tcx>>,
|
||||
unwind_context: &mut UnwindContext<'tcx>,
|
||||
mono_items: Vec<(MonoItem<'tcx>, (RLinkage, Visibility))>,
|
||||
) {
|
||||
let mut cx = CodegenCx::new(tcx, module, debug_context);
|
||||
let mut cx = CodegenCx::new(tcx, module, debug_context, unwind_context);
|
||||
|
||||
tcx.sess.time("predefine functions", || {
|
||||
for &(mono_item, (linkage, visibility)) in &mono_items {
|
||||
|
@ -106,7 +106,7 @@ mod prelude {
|
||||
pub(crate) use crate::base::{trans_operand, trans_place};
|
||||
pub(crate) use crate::cast::*;
|
||||
pub(crate) use crate::common::*;
|
||||
pub(crate) use crate::debuginfo::{DebugContext, FunctionDebugContext};
|
||||
pub(crate) use crate::debuginfo::{DebugContext, FunctionDebugContext, UnwindContext};
|
||||
pub(crate) use crate::pointer::Pointer;
|
||||
pub(crate) use crate::trap::*;
|
||||
pub(crate) use crate::value_and_place::{CPlace, CPlaceInner, CValue};
|
||||
@ -133,6 +133,7 @@ pub(crate) struct CodegenCx<'clif, 'tcx, B: Backend + 'static> {
|
||||
cached_context: Context,
|
||||
vtables: FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), DataId>,
|
||||
debug_context: Option<&'clif mut DebugContext<'tcx>>,
|
||||
unwind_context: &'clif mut UnwindContext<'tcx>,
|
||||
}
|
||||
|
||||
impl<'clif, 'tcx, B: Backend + 'static> CodegenCx<'clif, 'tcx, B> {
|
||||
@ -140,6 +141,7 @@ impl<'clif, 'tcx, B: Backend + 'static> CodegenCx<'clif, 'tcx, B> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
module: &'clif mut Module<B>,
|
||||
debug_context: Option<&'clif mut DebugContext<'tcx>>,
|
||||
unwind_context: &'clif mut UnwindContext<'tcx>,
|
||||
) -> Self {
|
||||
CodegenCx {
|
||||
tcx,
|
||||
@ -148,6 +150,7 @@ impl<'clif, 'tcx, B: Backend + 'static> CodegenCx<'clif, 'tcx, B> {
|
||||
cached_context: Context::new(),
|
||||
vtables: FxHashMap::default(),
|
||||
debug_context,
|
||||
unwind_context,
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user