Always emit .eh_frame section

This commit is contained in:
bjorn3 2020-05-01 19:21:29 +02:00
parent 485e52e153
commit 4da6488d95
9 changed files with 82 additions and 54 deletions

View File

@ -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???")
}
};

View File

@ -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

View File

@ -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 &section.relocs {
product.add_debug_reloc(&section_map, &self.symbols, section_id, reloc);
product.add_debug_reloc(&section_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(&section_map, &self.symbols, &section_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),
}
}
}

View File

@ -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

View File

@ -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(&section_map, &section_id, reloc);
}
}
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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 {

View File

@ -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,
}
}