Allow debuginfo to reference global variables
This commit is contained in:
parent
1f75f0fcad
commit
f086e7abaf
@ -1,5 +1,6 @@
|
|||||||
//! Write the debuginfo into an object file.
|
//! Write the debuginfo into an object file.
|
||||||
|
|
||||||
|
use cranelift_module::{DataId, FuncId};
|
||||||
use cranelift_object::ObjectProduct;
|
use cranelift_object::ObjectProduct;
|
||||||
use gimli::write::{Address, AttributeValue, EndianVec, Result, Sections, Writer};
|
use gimli::write::{Address, AttributeValue, EndianVec, Result, Sections, Writer};
|
||||||
use gimli::{RunTimeEndian, SectionId};
|
use gimli::{RunTimeEndian, SectionId};
|
||||||
@ -8,6 +9,19 @@
|
|||||||
use super::object::WriteDebugInfo;
|
use super::object::WriteDebugInfo;
|
||||||
use super::DebugContext;
|
use super::DebugContext;
|
||||||
|
|
||||||
|
pub(super) fn address_for_func(func_id: FuncId) -> Address {
|
||||||
|
let symbol = func_id.as_u32();
|
||||||
|
assert!(symbol & 1 << 31 == 0);
|
||||||
|
Address::Symbol { symbol: symbol as usize, addend: 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub(super) fn address_for_data(data_id: DataId) -> Address {
|
||||||
|
let symbol = data_id.as_u32();
|
||||||
|
assert!(symbol & 1 << 31 == 0);
|
||||||
|
Address::Symbol { symbol: (symbol | 1 << 31) as usize, addend: 0 }
|
||||||
|
}
|
||||||
|
|
||||||
impl DebugContext {
|
impl DebugContext {
|
||||||
pub(crate) fn emit(&mut self, product: &mut ObjectProduct) {
|
pub(crate) fn emit(&mut self, product: &mut ObjectProduct) {
|
||||||
let unit_range_list_id = self.dwarf.unit.ranges.add(self.unit_range_list.clone());
|
let unit_range_list_id = self.dwarf.unit.ranges.add(self.unit_range_list.clone());
|
||||||
@ -171,6 +185,7 @@ fn write_eh_pointer(&mut self, address: Address, eh_pe: gimli::DwEhPe, size: u8)
|
|||||||
gimli::DW_EH_PE_pcrel => {
|
gimli::DW_EH_PE_pcrel => {
|
||||||
let size = match eh_pe.format() {
|
let size = match eh_pe.format() {
|
||||||
gimli::DW_EH_PE_sdata4 => 4,
|
gimli::DW_EH_PE_sdata4 => 4,
|
||||||
|
gimli::DW_EH_PE_sdata8 => 8,
|
||||||
_ => return Err(gimli::write::Error::UnsupportedPointerEncoding(eh_pe)),
|
_ => return Err(gimli::write::Error::UnsupportedPointerEncoding(eh_pe)),
|
||||||
};
|
};
|
||||||
self.relocs.push(DebugReloc {
|
self.relocs.push(DebugReloc {
|
||||||
|
@ -5,13 +5,12 @@
|
|||||||
|
|
||||||
use cranelift_codegen::binemit::CodeOffset;
|
use cranelift_codegen::binemit::CodeOffset;
|
||||||
use cranelift_codegen::MachSrcLoc;
|
use cranelift_codegen::MachSrcLoc;
|
||||||
use gimli::write::{
|
use gimli::write::{AttributeValue, FileId, FileInfo, LineProgram, LineString, LineStringTable};
|
||||||
Address, AttributeValue, FileId, FileInfo, LineProgram, LineString, LineStringTable,
|
|
||||||
};
|
|
||||||
use rustc_span::{
|
use rustc_span::{
|
||||||
FileName, Pos, SourceFile, SourceFileAndLine, SourceFileHash, SourceFileHashAlgorithm,
|
FileName, Pos, SourceFile, SourceFileAndLine, SourceFileHash, SourceFileHashAlgorithm,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::debuginfo::emit::address_for_func;
|
||||||
use crate::debuginfo::FunctionDebugContext;
|
use crate::debuginfo::FunctionDebugContext;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
@ -143,7 +142,7 @@ pub(crate) fn add_dbg_loc(&mut self, file_id: FileId, line: u64, column: u64) ->
|
|||||||
pub(super) fn create_debug_lines(
|
pub(super) fn create_debug_lines(
|
||||||
&mut self,
|
&mut self,
|
||||||
debug_context: &mut DebugContext,
|
debug_context: &mut DebugContext,
|
||||||
symbol: usize,
|
func_id: FuncId,
|
||||||
context: &Context,
|
context: &Context,
|
||||||
) -> CodeOffset {
|
) -> CodeOffset {
|
||||||
let create_row_for_span =
|
let create_row_for_span =
|
||||||
@ -156,11 +155,7 @@ pub(super) fn create_debug_lines(
|
|||||||
debug_context.dwarf.unit.line_program.generate_row();
|
debug_context.dwarf.unit.line_program.generate_row();
|
||||||
};
|
};
|
||||||
|
|
||||||
debug_context
|
debug_context.dwarf.unit.line_program.begin_sequence(Some(address_for_func(func_id)));
|
||||||
.dwarf
|
|
||||||
.unit
|
|
||||||
.line_program
|
|
||||||
.begin_sequence(Some(Address::Symbol { symbol, addend: 0 }));
|
|
||||||
|
|
||||||
let mut func_end = 0;
|
let mut func_end = 0;
|
||||||
|
|
||||||
@ -183,10 +178,7 @@ pub(super) fn create_debug_lines(
|
|||||||
assert_ne!(func_end, 0);
|
assert_ne!(func_end, 0);
|
||||||
|
|
||||||
let entry = debug_context.dwarf.unit.get_mut(self.entry_id);
|
let entry = debug_context.dwarf.unit.get_mut(self.entry_id);
|
||||||
entry.set(
|
entry.set(gimli::DW_AT_low_pc, AttributeValue::Address(address_for_func(func_id)));
|
||||||
gimli::DW_AT_low_pc,
|
|
||||||
AttributeValue::Address(Address::Symbol { symbol, addend: 0 }),
|
|
||||||
);
|
|
||||||
entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(func_end)));
|
entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(func_end)));
|
||||||
|
|
||||||
func_end
|
func_end
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
pub(crate) use self::emit::{DebugReloc, DebugRelocName};
|
pub(crate) use self::emit::{DebugReloc, DebugRelocName};
|
||||||
pub(crate) use self::unwind::UnwindContext;
|
pub(crate) use self::unwind::UnwindContext;
|
||||||
|
use crate::debuginfo::emit::address_for_func;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
pub(crate) fn producer(sess: &Session) -> String {
|
pub(crate) fn producer(sess: &Session) -> String {
|
||||||
@ -174,7 +175,6 @@ pub(crate) fn define_function<'tcx>(
|
|||||||
) -> FunctionDebugContext {
|
) -> FunctionDebugContext {
|
||||||
let (file_id, line, column) = self.get_span_loc(tcx, function_span, function_span);
|
let (file_id, line, column) = self.get_span_loc(tcx, function_span, function_span);
|
||||||
|
|
||||||
// FIXME: add to appropriate scope instead of root
|
|
||||||
let scope = self.item_namespace(tcx, tcx.parent(instance.def_id()));
|
let scope = self.item_namespace(tcx, tcx.parent(instance.def_id()));
|
||||||
|
|
||||||
let mut name = String::new();
|
let mut name = String::new();
|
||||||
@ -240,21 +240,16 @@ pub(crate) fn finalize(
|
|||||||
func_id: FuncId,
|
func_id: FuncId,
|
||||||
context: &Context,
|
context: &Context,
|
||||||
) {
|
) {
|
||||||
let symbol = func_id.as_u32() as usize;
|
let end = self.create_debug_lines(debug_context, func_id, context);
|
||||||
|
|
||||||
let end = self.create_debug_lines(debug_context, symbol, context);
|
debug_context
|
||||||
|
.unit_range_list
|
||||||
debug_context.unit_range_list.0.push(Range::StartLength {
|
.0
|
||||||
begin: Address::Symbol { symbol, addend: 0 },
|
.push(Range::StartLength { begin: address_for_func(func_id), length: u64::from(end) });
|
||||||
length: u64::from(end),
|
|
||||||
});
|
|
||||||
|
|
||||||
let func_entry = debug_context.dwarf.unit.get_mut(self.entry_id);
|
let func_entry = debug_context.dwarf.unit.get_mut(self.entry_id);
|
||||||
// Gdb requires both DW_AT_low_pc and DW_AT_high_pc. Otherwise the DW_TAG_subprogram is skipped.
|
// Gdb requires both DW_AT_low_pc and DW_AT_high_pc. Otherwise the DW_TAG_subprogram is skipped.
|
||||||
func_entry.set(
|
func_entry.set(gimli::DW_AT_low_pc, AttributeValue::Address(address_for_func(func_id)));
|
||||||
gimli::DW_AT_low_pc,
|
|
||||||
AttributeValue::Address(Address::Symbol { symbol, addend: 0 }),
|
|
||||||
);
|
|
||||||
// Using Udata for DW_AT_high_pc requires at least DWARF4
|
// Using Udata for DW_AT_high_pc requires at least DWARF4
|
||||||
func_entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(end)));
|
func_entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(end)));
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use cranelift_module::FuncId;
|
use cranelift_module::{DataId, FuncId};
|
||||||
use cranelift_object::ObjectProduct;
|
use cranelift_object::ObjectProduct;
|
||||||
use gimli::SectionId;
|
use gimli::SectionId;
|
||||||
use object::write::{Relocation, StandardSegment};
|
use object::write::{Relocation, StandardSegment};
|
||||||
@ -57,10 +57,13 @@ fn add_debug_reloc(
|
|||||||
let (symbol, symbol_offset) = match reloc.name {
|
let (symbol, symbol_offset) = match reloc.name {
|
||||||
DebugRelocName::Section(id) => (section_map.get(&id).unwrap().1, 0),
|
DebugRelocName::Section(id) => (section_map.get(&id).unwrap().1, 0),
|
||||||
DebugRelocName::Symbol(id) => {
|
DebugRelocName::Symbol(id) => {
|
||||||
let symbol_id = self.function_symbol(FuncId::from_u32(id.try_into().unwrap()));
|
let id = id.try_into().unwrap();
|
||||||
self.object
|
let symbol_id = if id & 1 << 31 == 0 {
|
||||||
.symbol_section_and_offset(symbol_id)
|
self.function_symbol(FuncId::from_u32(id))
|
||||||
.expect("Debug reloc for undef sym???")
|
} else {
|
||||||
|
self.data_symbol(DataId::from_u32(id & !(1 << 31)))
|
||||||
|
};
|
||||||
|
self.object.symbol_section_and_offset(symbol_id).unwrap_or((symbol_id, 0))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
self.object
|
self.object
|
||||||
|
@ -3,9 +3,10 @@
|
|||||||
use cranelift_codegen::ir::Endianness;
|
use cranelift_codegen::ir::Endianness;
|
||||||
use cranelift_codegen::isa::{unwind::UnwindInfo, TargetIsa};
|
use cranelift_codegen::isa::{unwind::UnwindInfo, TargetIsa};
|
||||||
use cranelift_object::ObjectProduct;
|
use cranelift_object::ObjectProduct;
|
||||||
use gimli::write::{Address, CieId, EhFrame, FrameTable, Section};
|
use gimli::write::{CieId, EhFrame, FrameTable, Section};
|
||||||
use gimli::RunTimeEndian;
|
use gimli::RunTimeEndian;
|
||||||
|
|
||||||
|
use super::emit::address_for_func;
|
||||||
use super::object::WriteDebugInfo;
|
use super::object::WriteDebugInfo;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
@ -47,11 +48,8 @@ pub(crate) fn add_function(&mut self, func_id: FuncId, context: &Context, isa: &
|
|||||||
|
|
||||||
match unwind_info {
|
match unwind_info {
|
||||||
UnwindInfo::SystemV(unwind_info) => {
|
UnwindInfo::SystemV(unwind_info) => {
|
||||||
self.frame_table.add_fde(
|
self.frame_table
|
||||||
self.cie_id.unwrap(),
|
.add_fde(self.cie_id.unwrap(), unwind_info.to_fde(address_for_func(func_id)));
|
||||||
unwind_info
|
|
||||||
.to_fde(Address::Symbol { symbol: func_id.as_u32() as usize, addend: 0 }),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
UnwindInfo::WindowsX64(_) => {
|
UnwindInfo::WindowsX64(_) => {
|
||||||
// FIXME implement this
|
// FIXME implement this
|
||||||
|
Loading…
Reference in New Issue
Block a user