Don't generate DWARF sections when no functions were compiled. (#894)

This commit is contained in:
Yury Delendik
2020-02-03 14:41:29 -06:00
committed by GitHub
parent ea4faa4a01
commit 4599234c6f
8 changed files with 138 additions and 62 deletions

View File

@@ -7,14 +7,28 @@ use wasmtime_environ::entity::EntityRef;
use wasmtime_environ::ir::{StackSlots, ValueLabel, ValueLabelsRanges, ValueLoc};
use wasmtime_environ::isa::RegUnit;
use wasmtime_environ::wasm::{get_vmctx_value_label, DefinedFuncIndex};
use wasmtime_environ::ModuleMemoryOffset;
#[derive(Debug)]
pub struct FunctionFrameInfo<'a> {
pub value_ranges: &'a ValueLabelsRanges,
pub memory_offset: i64,
pub memory_offset: ModuleMemoryOffset,
pub stack_slots: &'a StackSlots,
}
impl<'a> FunctionFrameInfo<'a> {
fn vmctx_memory_offset(&self) -> Option<i64> {
match self.memory_offset {
ModuleMemoryOffset::Defined(x) => Some(x as i64),
ModuleMemoryOffset::Imported(_) => {
// TODO implement memory offset for imported memory
None
}
ModuleMemoryOffset::None => None,
}
}
}
#[derive(Debug)]
enum CompiledExpressionPart {
Code(Vec<u8>),
@@ -142,20 +156,32 @@ fn append_memory_deref(
) -> write::Result<bool> {
use gimli::write::Writer;
let mut writer = write::EndianVec::new(endian);
// FIXME for imported memory
match vmctx_loc {
ValueLoc::Reg(vmctx_reg) => {
let reg = map_reg(vmctx_reg);
writer.write_u8(gimli::constants::DW_OP_breg0.0 + reg.0 as u8)?;
writer.write_sleb128(frame_info.memory_offset)?;
let memory_offset = match frame_info.vmctx_memory_offset() {
Some(offset) => offset,
None => {
return Ok(false);
}
};
writer.write_sleb128(memory_offset)?;
}
ValueLoc::Stack(ss) => {
if let Some(ss_offset) = frame_info.stack_slots[ss].offset {
writer.write_u8(gimli::constants::DW_OP_breg0.0 + X86_64::RBP.0 as u8)?;
writer.write_sleb128(ss_offset as i64 + 16)?;
writer.write_u8(gimli::constants::DW_OP_deref.0 as u8)?;
writer.write_u8(gimli::constants::DW_OP_consts.0 as u8)?;
writer.write_sleb128(frame_info.memory_offset)?;
let memory_offset = match frame_info.vmctx_memory_offset() {
Some(offset) => offset,
None => {
return Ok(false);
}
};
writer.write_sleb128(memory_offset)?;
writer.write_u8(gimli::constants::DW_OP_plus.0 as u8)?;
} else {
return Ok(false);

View File

@@ -3,7 +3,7 @@ use super::expression::{CompiledExpression, FunctionFrameInfo};
use anyhow::Error;
use gimli::write;
use wasmtime_environ::wasm::DefinedFuncIndex;
use wasmtime_environ::{ModuleVmctxInfo, ValueLabelsRanges};
use wasmtime_environ::{ModuleMemoryOffset, ModuleVmctxInfo, ValueLabelsRanges};
pub(crate) fn add_internal_types(
comp_unit: &mut write::Unit,
@@ -46,32 +46,46 @@ pub(crate) fn add_internal_types(
write::AttributeValue::ThisUnitEntryRef(memory_byte_die_id),
);
let memory_offset = module_info.memory_offset;
// Create artificial VMContext type and its reference for convinience viewing
// its fields (such as memory ref) in a debugger.
let vmctx_die_id = comp_unit.add(root_id, gimli::DW_TAG_structure_type);
let vmctx_die = comp_unit.get_mut(vmctx_die_id);
vmctx_die.set(
gimli::DW_AT_name,
write::AttributeValue::StringRef(out_strings.add("WasmtimeVMContext")),
);
vmctx_die.set(
gimli::DW_AT_byte_size,
write::AttributeValue::Data4(memory_offset as u32 + 8),
);
let m_die_id = comp_unit.add(vmctx_die_id, gimli::DW_TAG_member);
let m_die = comp_unit.get_mut(m_die_id);
m_die.set(
gimli::DW_AT_name,
write::AttributeValue::StringRef(out_strings.add("memory")),
);
m_die.set(
gimli::DW_AT_type,
write::AttributeValue::ThisUnitEntryRef(memory_bytes_die_id),
);
m_die.set(
gimli::DW_AT_data_member_location,
write::AttributeValue::Udata(memory_offset as u64),
);
match module_info.memory_offset {
ModuleMemoryOffset::Defined(memory_offset) => {
// The context has defined memory: extend the WasmtimeVMContext size
// past the "memory" field.
const MEMORY_FIELD_SIZE_PLUS_PADDING: u32 = 8;
vmctx_die.set(
gimli::DW_AT_byte_size,
write::AttributeValue::Data4(memory_offset + MEMORY_FIELD_SIZE_PLUS_PADDING),
);
// Define the "memory" field which is a direct pointer to allocated Wasm memory.
let m_die_id = comp_unit.add(vmctx_die_id, gimli::DW_TAG_member);
let m_die = comp_unit.get_mut(m_die_id);
m_die.set(
gimli::DW_AT_name,
write::AttributeValue::StringRef(out_strings.add("memory")),
);
m_die.set(
gimli::DW_AT_type,
write::AttributeValue::ThisUnitEntryRef(memory_bytes_die_id),
);
m_die.set(
gimli::DW_AT_data_member_location,
write::AttributeValue::Udata(memory_offset as u64),
);
}
ModuleMemoryOffset::Imported(_) => {
// TODO implement convinience pointer to and additional types for VMMemoryImport.
}
ModuleMemoryOffset::None => (),
}
let vmctx_ptr_die_id = comp_unit.add(root_id, gimli::DW_TAG_pointer_type);
let vmctx_ptr_die = comp_unit.get_mut(vmctx_ptr_die_id);
@@ -141,7 +155,7 @@ where
if let Some(value_ranges) = value_ranges.get(func_index) {
let frame_info = FunctionFrameInfo {
value_ranges,
memory_offset: module_info.memory_offset,
memory_offset: module_info.memory_offset.clone(),
stack_slots: &module_info.stack_slots[func_index],
};
Some(frame_info)