Removes panic! from the debug crate. (#1261)
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
use anyhow::{bail, Result};
|
||||||
use gimli::{
|
use gimli::{
|
||||||
DebugAbbrev, DebugAddr, DebugInfo, DebugLine, DebugLineStr, DebugLoc, DebugLocLists,
|
DebugAbbrev, DebugAddr, DebugInfo, DebugLine, DebugLineStr, DebugLoc, DebugLocLists,
|
||||||
DebugRanges, DebugRngLists, DebugStr, DebugStrOffsets, DebugTypes, EndianSlice, LittleEndian,
|
DebugRanges, DebugRngLists, DebugStr, DebugStrOffsets, DebugTypes, EndianSlice, LittleEndian,
|
||||||
@@ -42,7 +43,7 @@ pub struct DebugInfoData<'a> {
|
|||||||
pub wasm_file: WasmFileInfo,
|
pub wasm_file: WasmFileInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_sections<'a>(sections: HashMap<&str, &'a [u8]>) -> Dwarf<'a> {
|
fn convert_sections<'a>(sections: HashMap<&str, &'a [u8]>) -> Result<Dwarf<'a>> {
|
||||||
const EMPTY_SECTION: &[u8] = &[];
|
const EMPTY_SECTION: &[u8] = &[];
|
||||||
|
|
||||||
let endian = LittleEndian;
|
let endian = LittleEndian;
|
||||||
@@ -61,20 +62,20 @@ fn convert_sections<'a>(sections: HashMap<&str, &'a [u8]>) -> Dwarf<'a> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if sections.contains_key(".debug_addr") {
|
if sections.contains_key(".debug_addr") {
|
||||||
panic!("Unexpected .debug_addr");
|
bail!("Unexpected .debug_addr");
|
||||||
}
|
}
|
||||||
|
|
||||||
let debug_addr = DebugAddr::from(EndianSlice::new(EMPTY_SECTION, endian));
|
let debug_addr = DebugAddr::from(EndianSlice::new(EMPTY_SECTION, endian));
|
||||||
|
|
||||||
if sections.contains_key(".debug_line_str") {
|
if sections.contains_key(".debug_line_str") {
|
||||||
panic!("Unexpected .debug_line_str");
|
bail!("Unexpected .debug_line_str");
|
||||||
}
|
}
|
||||||
|
|
||||||
let debug_line_str = DebugLineStr::from(EndianSlice::new(EMPTY_SECTION, endian));
|
let debug_line_str = DebugLineStr::from(EndianSlice::new(EMPTY_SECTION, endian));
|
||||||
let debug_str_sup = DebugStr::from(EndianSlice::new(EMPTY_SECTION, endian));
|
let debug_str_sup = DebugStr::from(EndianSlice::new(EMPTY_SECTION, endian));
|
||||||
|
|
||||||
if sections.contains_key(".debug_rnglists") {
|
if sections.contains_key(".debug_rnglists") {
|
||||||
panic!("Unexpected .debug_rnglists");
|
bail!("Unexpected .debug_rnglists");
|
||||||
}
|
}
|
||||||
|
|
||||||
let debug_ranges = match sections.get(".debug_ranges") {
|
let debug_ranges = match sections.get(".debug_ranges") {
|
||||||
@@ -85,7 +86,7 @@ fn convert_sections<'a>(sections: HashMap<&str, &'a [u8]>) -> Dwarf<'a> {
|
|||||||
let ranges = RangeLists::new(debug_ranges, debug_rnglists);
|
let ranges = RangeLists::new(debug_ranges, debug_rnglists);
|
||||||
|
|
||||||
if sections.contains_key(".debug_loclists") {
|
if sections.contains_key(".debug_loclists") {
|
||||||
panic!("Unexpected .debug_loclists");
|
bail!("Unexpected .debug_loclists");
|
||||||
}
|
}
|
||||||
|
|
||||||
let debug_loc = match sections.get(".debug_loc") {
|
let debug_loc = match sections.get(".debug_loc") {
|
||||||
@@ -96,18 +97,18 @@ fn convert_sections<'a>(sections: HashMap<&str, &'a [u8]>) -> Dwarf<'a> {
|
|||||||
let locations = LocationLists::new(debug_loc, debug_loclists);
|
let locations = LocationLists::new(debug_loc, debug_loclists);
|
||||||
|
|
||||||
if sections.contains_key(".debug_str_offsets") {
|
if sections.contains_key(".debug_str_offsets") {
|
||||||
panic!("Unexpected .debug_str_offsets");
|
bail!("Unexpected .debug_str_offsets");
|
||||||
}
|
}
|
||||||
|
|
||||||
let debug_str_offsets = DebugStrOffsets::from(EndianSlice::new(EMPTY_SECTION, endian));
|
let debug_str_offsets = DebugStrOffsets::from(EndianSlice::new(EMPTY_SECTION, endian));
|
||||||
|
|
||||||
if sections.contains_key(".debug_types") {
|
if sections.contains_key(".debug_types") {
|
||||||
panic!("Unexpected .debug_types");
|
bail!("Unexpected .debug_types");
|
||||||
}
|
}
|
||||||
|
|
||||||
let debug_types = DebugTypes::from(EndianSlice::new(EMPTY_SECTION, endian));
|
let debug_types = DebugTypes::from(EndianSlice::new(EMPTY_SECTION, endian));
|
||||||
|
|
||||||
Dwarf {
|
Ok(Dwarf {
|
||||||
debug_abbrev,
|
debug_abbrev,
|
||||||
debug_addr,
|
debug_addr,
|
||||||
debug_info,
|
debug_info,
|
||||||
@@ -119,7 +120,7 @@ fn convert_sections<'a>(sections: HashMap<&str, &'a [u8]>) -> Dwarf<'a> {
|
|||||||
debug_types,
|
debug_types,
|
||||||
locations,
|
locations,
|
||||||
ranges,
|
ranges,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_name_section(reader: wasmparser::NameSectionReader) -> wasmparser::Result<NameSection> {
|
fn read_name_section(reader: wasmparser::NameSectionReader) -> wasmparser::Result<NameSection> {
|
||||||
@@ -158,8 +159,8 @@ fn read_name_section(reader: wasmparser::NameSectionReader) -> wasmparser::Resul
|
|||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_debuginfo(data: &[u8]) -> DebugInfoData {
|
pub fn read_debuginfo(data: &[u8]) -> Result<DebugInfoData> {
|
||||||
let mut reader = ModuleReader::new(data).expect("reader");
|
let mut reader = ModuleReader::new(data)?;
|
||||||
let mut sections = HashMap::new();
|
let mut sections = HashMap::new();
|
||||||
let mut name_section = None;
|
let mut name_section = None;
|
||||||
let mut code_section_offset = 0;
|
let mut code_section_offset = 0;
|
||||||
@@ -169,13 +170,13 @@ pub fn read_debuginfo(data: &[u8]) -> DebugInfoData {
|
|||||||
let mut func_locals: Vec<Box<[(u32, WasmType)]>> = Vec::new();
|
let mut func_locals: Vec<Box<[(u32, WasmType)]>> = Vec::new();
|
||||||
|
|
||||||
while !reader.eof() {
|
while !reader.eof() {
|
||||||
let section = reader.read().expect("section");
|
let section = reader.read()?;
|
||||||
match section.code {
|
match section.code {
|
||||||
SectionCode::Custom { name, .. } => {
|
SectionCode::Custom { name, .. } => {
|
||||||
if name.starts_with(".debug_") {
|
if name.starts_with(".debug_") {
|
||||||
let mut reader = section.get_binary_reader();
|
let mut reader = section.get_binary_reader();
|
||||||
let len = reader.bytes_remaining();
|
let len = reader.bytes_remaining();
|
||||||
sections.insert(name, reader.read_bytes(len).expect("bytes"));
|
sections.insert(name, reader.read_bytes(len)?);
|
||||||
}
|
}
|
||||||
if name == "name" {
|
if name == "name" {
|
||||||
if let Ok(reader) = section.get_name_section_reader() {
|
if let Ok(reader) = section.get_name_section_reader() {
|
||||||
@@ -187,38 +188,31 @@ pub fn read_debuginfo(data: &[u8]) -> DebugInfoData {
|
|||||||
}
|
}
|
||||||
SectionCode::Type => {
|
SectionCode::Type => {
|
||||||
signatures_params = section
|
signatures_params = section
|
||||||
.get_type_section_reader()
|
.get_type_section_reader()?
|
||||||
.expect("type section")
|
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|ft| ft.expect("type").params)
|
.map(|ft| Ok(ft?.params))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Result<Vec<_>>>()?;
|
||||||
}
|
}
|
||||||
SectionCode::Function => {
|
SectionCode::Function => {
|
||||||
func_params_refs = section
|
func_params_refs = section
|
||||||
.get_function_section_reader()
|
.get_function_section_reader()?
|
||||||
.expect("function section")
|
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|index| index.expect("func index") as usize)
|
.map(|index| Ok(index? as usize))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Result<Vec<_>>>()?;
|
||||||
}
|
}
|
||||||
SectionCode::Code => {
|
SectionCode::Code => {
|
||||||
code_section_offset = section.range().start as u64;
|
code_section_offset = section.range().start as u64;
|
||||||
func_locals = section
|
func_locals = section
|
||||||
.get_code_section_reader()
|
.get_code_section_reader()?
|
||||||
.expect("code section")
|
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|body| {
|
.map(|body| {
|
||||||
let locals = body
|
let locals = body?.get_locals_reader()?;
|
||||||
.expect("body")
|
Ok(locals
|
||||||
.get_locals_reader()
|
|
||||||
.expect("locals reader");
|
|
||||||
locals
|
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.collect::<Result<Vec<_>, _>>()
|
.collect::<Result<Vec<_>, _>>()?
|
||||||
.expect("locals data")
|
.into_boxed_slice())
|
||||||
.into_boxed_slice()
|
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Result<Vec<_>>>()?;
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
@@ -233,13 +227,14 @@ pub fn read_debuginfo(data: &[u8]) -> DebugInfoData {
|
|||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
DebugInfoData {
|
let dwarf = convert_sections(sections)?;
|
||||||
dwarf: convert_sections(sections),
|
Ok(DebugInfoData {
|
||||||
|
dwarf,
|
||||||
name_section,
|
name_section,
|
||||||
wasm_file: WasmFileInfo {
|
wasm_file: WasmFileInfo {
|
||||||
path: None,
|
path: None,
|
||||||
code_section_offset,
|
code_section_offset,
|
||||||
funcs: func_meta.into_boxed_slice(),
|
funcs: func_meta.into_boxed_slice(),
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use super::expression::{compile_expression, CompiledExpression, FunctionFrameInf
|
|||||||
use super::range_info_builder::RangeInfoBuilder;
|
use super::range_info_builder::RangeInfoBuilder;
|
||||||
use super::refs::{PendingDebugInfoRefs, PendingUnitRefs};
|
use super::refs::{PendingDebugInfoRefs, PendingUnitRefs};
|
||||||
use super::{DebugInputContext, Reader, TransformError};
|
use super::{DebugInputContext, Reader, TransformError};
|
||||||
use anyhow::Error;
|
use anyhow::{bail, Error};
|
||||||
use gimli::{write, AttributeValue, DebugLineOffset, DebugStr, DebuggingInformationEntry};
|
use gimli::{write, AttributeValue, DebugLineOffset, DebugStr, DebuggingInformationEntry};
|
||||||
use wasmtime_environ::isa::TargetIsa;
|
use wasmtime_environ::isa::TargetIsa;
|
||||||
|
|
||||||
@@ -143,7 +143,7 @@ where
|
|||||||
addr_tr,
|
addr_tr,
|
||||||
frame_info,
|
frame_info,
|
||||||
endian,
|
endian,
|
||||||
) {
|
)? {
|
||||||
if len == 0 {
|
if len == 0 {
|
||||||
// Ignore empty range
|
// Ignore empty range
|
||||||
continue;
|
continue;
|
||||||
@@ -183,7 +183,7 @@ where
|
|||||||
// Conversion to loclist is required.
|
// Conversion to loclist is required.
|
||||||
if let Some(scope_ranges) = scope_ranges {
|
if let Some(scope_ranges) = scope_ranges {
|
||||||
let exprs =
|
let exprs =
|
||||||
expr.build_with_locals(scope_ranges, addr_tr, frame_info, endian);
|
expr.build_with_locals(scope_ranges, addr_tr, frame_info, endian)?;
|
||||||
if exprs.is_empty() {
|
if exprs.is_empty() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -252,7 +252,7 @@ where
|
|||||||
pending_di_refs.insert(current_scope_id, attr.name(), offset);
|
pending_di_refs.insert(current_scope_id, attr.name(), offset);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
_ => panic!(), //write::AttributeValue::StringRef(out_strings.add("_")),
|
a => bail!("Unexpected attribute: {:?}", a),
|
||||||
};
|
};
|
||||||
let current_scope = out_unit.get_mut(current_scope_id);
|
let current_scope = out_unit.get_mut(current_scope_id);
|
||||||
current_scope.set(attr.name(), attr_value);
|
current_scope.set(attr.name(), attr_value);
|
||||||
@@ -265,7 +265,7 @@ pub(crate) fn clone_attr_string<R>(
|
|||||||
form: gimli::DwForm,
|
form: gimli::DwForm,
|
||||||
debug_str: &DebugStr<R>,
|
debug_str: &DebugStr<R>,
|
||||||
out_strings: &mut write::StringTable,
|
out_strings: &mut write::StringTable,
|
||||||
) -> Result<write::LineString, gimli::Error>
|
) -> Result<write::LineString, Error>
|
||||||
where
|
where
|
||||||
R: Reader,
|
R: Reader,
|
||||||
{
|
{
|
||||||
@@ -274,7 +274,7 @@ where
|
|||||||
debug_str.get_str(*str_offset)?.to_slice()?.to_vec()
|
debug_str.get_str(*str_offset)?.to_slice()?.to_vec()
|
||||||
}
|
}
|
||||||
AttributeValue::String(b) => b.to_slice()?.to_vec(),
|
AttributeValue::String(b) => b.to_slice()?.to_vec(),
|
||||||
_ => panic!("Unexpected attribute value"),
|
v => bail!("Unexpected attribute value: {:?}", v),
|
||||||
};
|
};
|
||||||
Ok(match form {
|
Ok(match form {
|
||||||
gimli::DW_FORM_strp => {
|
gimli::DW_FORM_strp => {
|
||||||
@@ -282,6 +282,6 @@ where
|
|||||||
write::LineString::StringRef(id)
|
write::LineString::StringRef(id)
|
||||||
}
|
}
|
||||||
gimli::DW_FORM_string => write::LineString::String(content),
|
gimli::DW_FORM_string => write::LineString::String(content),
|
||||||
_ => panic!("DW_FORM_line_strp or other not supported"),
|
_ => bail!("DW_FORM_line_strp or other not supported"),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use super::address_transform::AddressTransform;
|
use super::address_transform::AddressTransform;
|
||||||
use anyhow::Error;
|
use anyhow::{bail, Context, Error, Result};
|
||||||
use gimli::{self, write, Expression, Operation, Reader, ReaderOffset, Register, X86_64};
|
use gimli::{self, write, Expression, Operation, Reader, ReaderOffset, Register, X86_64};
|
||||||
use more_asserts::{assert_le, assert_lt};
|
use more_asserts::{assert_le, assert_lt};
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
@@ -70,7 +70,7 @@ impl<'a> CompiledExpression<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn map_reg(isa: &dyn TargetIsa, reg: RegUnit) -> Register {
|
fn map_reg(isa: &dyn TargetIsa, reg: RegUnit) -> Result<Register> {
|
||||||
// TODO avoid duplication with fde.rs
|
// TODO avoid duplication with fde.rs
|
||||||
assert!(isa.name() == "x86" && isa.pointer_bits() == 64);
|
assert!(isa.name() == "x86" && isa.pointer_bits() == 64);
|
||||||
// Mapping from https://github.com/bytecodealliance/cranelift/pull/902 by @iximeow
|
// Mapping from https://github.com/bytecodealliance/cranelift/pull/902 by @iximeow
|
||||||
@@ -116,11 +116,11 @@ fn map_reg(isa: &dyn TargetIsa, reg: RegUnit) -> Register {
|
|||||||
"IntRegs" => {
|
"IntRegs" => {
|
||||||
// x86 GP registers have a weird mapping to DWARF registers, so we use a
|
// x86 GP registers have a weird mapping to DWARF registers, so we use a
|
||||||
// lookup table.
|
// lookup table.
|
||||||
X86_GP_REG_MAP[(reg - bank.first_unit) as usize]
|
Ok(X86_GP_REG_MAP[(reg - bank.first_unit) as usize])
|
||||||
}
|
}
|
||||||
"FloatRegs" => X86_XMM_REG_MAP[(reg - bank.first_unit) as usize],
|
"FloatRegs" => Ok(X86_XMM_REG_MAP[(reg - bank.first_unit) as usize]),
|
||||||
_ => {
|
bank_name => {
|
||||||
panic!("unsupported register bank: {}", bank.name);
|
bail!("unsupported register bank: {}", bank_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -129,22 +129,18 @@ fn translate_loc(
|
|||||||
loc: ValueLoc,
|
loc: ValueLoc,
|
||||||
frame_info: Option<&FunctionFrameInfo>,
|
frame_info: Option<&FunctionFrameInfo>,
|
||||||
isa: &dyn TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
) -> Option<Vec<u8>> {
|
) -> Result<Option<Vec<u8>>> {
|
||||||
use gimli::write::Writer;
|
use gimli::write::Writer;
|
||||||
match loc {
|
Ok(match loc {
|
||||||
ValueLoc::Reg(reg) => {
|
ValueLoc::Reg(reg) => {
|
||||||
let machine_reg = map_reg(isa, reg).0 as u8;
|
let machine_reg = map_reg(isa, reg)?.0 as u8;
|
||||||
Some(if machine_reg < 32 {
|
Some(if machine_reg < 32 {
|
||||||
vec![gimli::constants::DW_OP_reg0.0 + machine_reg]
|
vec![gimli::constants::DW_OP_reg0.0 + machine_reg]
|
||||||
} else {
|
} else {
|
||||||
let endian = gimli::RunTimeEndian::Little;
|
let endian = gimli::RunTimeEndian::Little;
|
||||||
let mut writer = write::EndianVec::new(endian);
|
let mut writer = write::EndianVec::new(endian);
|
||||||
writer
|
writer.write_u8(gimli::constants::DW_OP_regx.0 as u8)?;
|
||||||
.write_u8(gimli::constants::DW_OP_regx.0 as u8)
|
writer.write_uleb128(machine_reg.into())?;
|
||||||
.expect("regx");
|
|
||||||
writer
|
|
||||||
.write_uleb128(machine_reg.into())
|
|
||||||
.expect("machine_reg");
|
|
||||||
writer.into_vec()
|
writer.into_vec()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -153,21 +149,17 @@ fn translate_loc(
|
|||||||
if let Some(ss_offset) = frame_info.stack_slots[ss].offset {
|
if let Some(ss_offset) = frame_info.stack_slots[ss].offset {
|
||||||
let endian = gimli::RunTimeEndian::Little;
|
let endian = gimli::RunTimeEndian::Little;
|
||||||
let mut writer = write::EndianVec::new(endian);
|
let mut writer = write::EndianVec::new(endian);
|
||||||
writer
|
writer.write_u8(gimli::constants::DW_OP_breg0.0 + X86_64::RBP.0 as u8)?;
|
||||||
.write_u8(gimli::constants::DW_OP_breg0.0 + X86_64::RBP.0 as u8)
|
writer.write_sleb128(ss_offset as i64 + 16)?;
|
||||||
.expect("bp wr");
|
writer.write_u8(gimli::constants::DW_OP_deref.0 as u8)?;
|
||||||
writer.write_sleb128(ss_offset as i64 + 16).expect("ss wr");
|
|
||||||
writer
|
|
||||||
.write_u8(gimli::constants::DW_OP_deref.0 as u8)
|
|
||||||
.expect("bp wr");
|
|
||||||
let buf = writer.into_vec();
|
let buf = writer.into_vec();
|
||||||
return Some(buf);
|
return Ok(Some(buf));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn append_memory_deref(
|
fn append_memory_deref(
|
||||||
@@ -176,13 +168,13 @@ fn append_memory_deref(
|
|||||||
vmctx_loc: ValueLoc,
|
vmctx_loc: ValueLoc,
|
||||||
endian: gimli::RunTimeEndian,
|
endian: gimli::RunTimeEndian,
|
||||||
isa: &dyn TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
) -> write::Result<bool> {
|
) -> Result<bool> {
|
||||||
use gimli::write::Writer;
|
use gimli::write::Writer;
|
||||||
let mut writer = write::EndianVec::new(endian);
|
let mut writer = write::EndianVec::new(endian);
|
||||||
// FIXME for imported memory
|
// FIXME for imported memory
|
||||||
match vmctx_loc {
|
match vmctx_loc {
|
||||||
ValueLoc::Reg(vmctx_reg) => {
|
ValueLoc::Reg(vmctx_reg) => {
|
||||||
let reg = map_reg(isa, vmctx_reg);
|
let reg = map_reg(isa, vmctx_reg)?;
|
||||||
writer.write_u8(gimli::constants::DW_OP_breg0.0 + reg.0 as u8)?;
|
writer.write_u8(gimli::constants::DW_OP_breg0.0 + reg.0 as u8)?;
|
||||||
let memory_offset = match frame_info.vmctx_memory_offset() {
|
let memory_offset = match frame_info.vmctx_memory_offset() {
|
||||||
Some(offset) => offset,
|
Some(offset) => offset,
|
||||||
@@ -248,9 +240,9 @@ impl<'a> CompiledExpression<'a> {
|
|||||||
addr_tr: &AddressTransform,
|
addr_tr: &AddressTransform,
|
||||||
frame_info: Option<&FunctionFrameInfo>,
|
frame_info: Option<&FunctionFrameInfo>,
|
||||||
endian: gimli::RunTimeEndian,
|
endian: gimli::RunTimeEndian,
|
||||||
) -> Vec<(write::Address, u64, write::Expression)> {
|
) -> Result<Vec<(write::Address, u64, write::Expression)>> {
|
||||||
if scope.is_empty() {
|
if scope.is_empty() {
|
||||||
return vec![];
|
return Ok(vec![]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let [CompiledExpressionPart::Code(code)] = self.parts.as_slice() {
|
if let [CompiledExpressionPart::Code(code)] = self.parts.as_slice() {
|
||||||
@@ -260,7 +252,7 @@ impl<'a> CompiledExpression<'a> {
|
|||||||
result_scope.push((addr, len, write::Expression(code.to_vec())));
|
result_scope.push((addr, len, write::Expression(code.to_vec())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result_scope;
|
return Ok(result_scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
let vmctx_label = get_vmctx_value_label();
|
let vmctx_label = get_vmctx_value_label();
|
||||||
@@ -295,8 +287,8 @@ impl<'a> CompiledExpression<'a> {
|
|||||||
match part {
|
match part {
|
||||||
CompiledExpressionPart::Code(c) => code_buf.extend_from_slice(c.as_slice()),
|
CompiledExpressionPart::Code(c) => code_buf.extend_from_slice(c.as_slice()),
|
||||||
CompiledExpressionPart::Local(label) => {
|
CompiledExpressionPart::Local(label) => {
|
||||||
let loc = *label_location.get(&label).expect("loc");
|
let loc = *label_location.get(&label).context("label_location")?;
|
||||||
if let Some(expr) = translate_loc(loc, frame_info, self.isa) {
|
if let Some(expr) = translate_loc(loc, frame_info, self.isa)? {
|
||||||
code_buf.extend_from_slice(&expr)
|
code_buf.extend_from_slice(&expr)
|
||||||
} else {
|
} else {
|
||||||
continue 'range;
|
continue 'range;
|
||||||
@@ -312,9 +304,7 @@ impl<'a> CompiledExpression<'a> {
|
|||||||
*vmctx_loc,
|
*vmctx_loc,
|
||||||
endian,
|
endian,
|
||||||
self.isa,
|
self.isa,
|
||||||
)
|
)? {
|
||||||
.expect("append_memory_deref")
|
|
||||||
{
|
|
||||||
continue 'range;
|
continue 'range;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -327,9 +317,13 @@ impl<'a> CompiledExpression<'a> {
|
|||||||
if let (Some(vmctx_loc), Some(frame_info)) =
|
if let (Some(vmctx_loc), Some(frame_info)) =
|
||||||
(label_location.get(&vmctx_label), frame_info)
|
(label_location.get(&vmctx_label), frame_info)
|
||||||
{
|
{
|
||||||
if !append_memory_deref(&mut code_buf, frame_info, *vmctx_loc, endian, self.isa)
|
if !append_memory_deref(
|
||||||
.expect("append_memory_deref")
|
&mut code_buf,
|
||||||
{
|
frame_info,
|
||||||
|
*vmctx_loc,
|
||||||
|
endian,
|
||||||
|
self.isa,
|
||||||
|
)? {
|
||||||
continue 'range;
|
continue 'range;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -346,7 +340,7 @@ impl<'a> CompiledExpression<'a> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
result
|
Ok(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use super::address_transform::AddressTransform;
|
use super::address_transform::AddressTransform;
|
||||||
use super::attr::clone_attr_string;
|
use super::attr::clone_attr_string;
|
||||||
use super::{Reader, TransformError};
|
use super::{Reader, TransformError};
|
||||||
use anyhow::Error;
|
use anyhow::{Context, Error};
|
||||||
use gimli::{
|
use gimli::{
|
||||||
write, DebugLine, DebugLineOffset, DebugStr, DebuggingInformationEntry, LineEncoding, Unit,
|
write, DebugLine, DebugLineOffset, DebugStr, DebuggingInformationEntry, LineEncoding, Unit,
|
||||||
};
|
};
|
||||||
@@ -56,13 +56,13 @@ where
|
|||||||
let comp_dir = root.attr_value(gimli::DW_AT_comp_dir)?;
|
let comp_dir = root.attr_value(gimli::DW_AT_comp_dir)?;
|
||||||
let comp_name = root.attr_value(gimli::DW_AT_name)?;
|
let comp_name = root.attr_value(gimli::DW_AT_name)?;
|
||||||
let out_comp_dir = clone_attr_string(
|
let out_comp_dir = clone_attr_string(
|
||||||
comp_dir.as_ref().expect("comp_dir"),
|
comp_dir.as_ref().context("comp_dir")?,
|
||||||
gimli::DW_FORM_strp,
|
gimli::DW_FORM_strp,
|
||||||
debug_str,
|
debug_str,
|
||||||
out_strings,
|
out_strings,
|
||||||
)?;
|
)?;
|
||||||
let out_comp_name = clone_attr_string(
|
let out_comp_name = clone_attr_string(
|
||||||
comp_name.as_ref().expect("comp_name"),
|
comp_name.as_ref().context("comp_name")?,
|
||||||
gimli::DW_FORM_strp,
|
gimli::DW_FORM_strp,
|
||||||
debug_str,
|
debug_str,
|
||||||
out_strings,
|
out_strings,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use super::expression::{CompiledExpression, FunctionFrameInfo};
|
|||||||
use super::utils::{add_internal_types, append_vmctx_info, get_function_frame_info};
|
use super::utils::{add_internal_types, append_vmctx_info, get_function_frame_info};
|
||||||
use super::AddressTransform;
|
use super::AddressTransform;
|
||||||
use crate::read_debuginfo::WasmFileInfo;
|
use crate::read_debuginfo::WasmFileInfo;
|
||||||
use anyhow::Error;
|
use anyhow::{Context, Error};
|
||||||
use gimli::write;
|
use gimli::write;
|
||||||
use gimli::{self, LineEncoding};
|
use gimli::{self, LineEncoding};
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
@@ -177,7 +177,7 @@ fn generate_vars(
|
|||||||
locals_names: Option<&HashMap<u32, String>>,
|
locals_names: Option<&HashMap<u32, String>>,
|
||||||
out_strings: &mut write::StringTable,
|
out_strings: &mut write::StringTable,
|
||||||
isa: &dyn TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
) {
|
) -> Result<(), Error> {
|
||||||
let vmctx_label = get_vmctx_value_label();
|
let vmctx_label = get_vmctx_value_label();
|
||||||
|
|
||||||
// Normalize order of ValueLabelsRanges keys to have reproducable results.
|
// Normalize order of ValueLabelsRanges keys to have reproducable results.
|
||||||
@@ -195,8 +195,7 @@ fn generate_vars(
|
|||||||
scope_ranges,
|
scope_ranges,
|
||||||
out_strings,
|
out_strings,
|
||||||
isa,
|
isa,
|
||||||
)
|
)?;
|
||||||
.expect("append_vmctx_info success");
|
|
||||||
} else {
|
} else {
|
||||||
let var_index = label.index();
|
let var_index = label.index();
|
||||||
let (type_die_id, is_param) =
|
let (type_die_id, is_param) =
|
||||||
@@ -213,7 +212,7 @@ fn generate_vars(
|
|||||||
let expr = CompiledExpression::from_label(*label, isa);
|
let expr = CompiledExpression::from_label(*label, isa);
|
||||||
let mut locs = Vec::new();
|
let mut locs = Vec::new();
|
||||||
for (begin, length, data) in
|
for (begin, length, data) in
|
||||||
expr.build_with_locals(scope_ranges, addr_tr, Some(frame_info), endian)
|
expr.build_with_locals(scope_ranges, addr_tr, Some(frame_info), endian)?
|
||||||
{
|
{
|
||||||
locs.push(write::Location::StartLength {
|
locs.push(write::Location::StartLength {
|
||||||
begin,
|
begin,
|
||||||
@@ -250,6 +249,7 @@ fn generate_vars(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_simulated_dwarf(
|
pub fn generate_simulated_dwarf(
|
||||||
@@ -279,8 +279,17 @@ pub fn generate_simulated_dwarf(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let (unit, root_id, name_id) = {
|
let (unit, root_id, name_id) = {
|
||||||
let comp_dir_id = out_strings.add(path.parent().expect("path dir").to_str().unwrap());
|
let comp_dir_id = out_strings.add(
|
||||||
let name = path.file_name().expect("path name").to_str().unwrap();
|
path.parent()
|
||||||
|
.context("path dir")?
|
||||||
|
.to_str()
|
||||||
|
.context("path dir encoding")?,
|
||||||
|
);
|
||||||
|
let name = path
|
||||||
|
.file_name()
|
||||||
|
.context("path name")?
|
||||||
|
.to_str()
|
||||||
|
.context("path name encoding")?;
|
||||||
let name_id = out_strings.add(name);
|
let name_id = out_strings.add(name);
|
||||||
|
|
||||||
let out_program = generate_line_info(
|
let out_program = generate_line_info(
|
||||||
@@ -370,7 +379,7 @@ pub fn generate_simulated_dwarf(
|
|||||||
locals_names.and_then(|m| m.get(&(index as u32))),
|
locals_names.and_then(|m| m.get(&(index as u32))),
|
||||||
out_strings,
|
out_strings,
|
||||||
isa,
|
isa,
|
||||||
);
|
)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use super::range_info_builder::RangeInfoBuilder;
|
|||||||
use super::refs::{PendingDebugInfoRefs, PendingUnitRefs, UnitRefsMap};
|
use super::refs::{PendingDebugInfoRefs, PendingUnitRefs, UnitRefsMap};
|
||||||
use super::utils::{add_internal_types, append_vmctx_info, get_function_frame_info};
|
use super::utils::{add_internal_types, append_vmctx_info, get_function_frame_info};
|
||||||
use super::{DebugInputContext, Reader, TransformError};
|
use super::{DebugInputContext, Reader, TransformError};
|
||||||
use anyhow::Error;
|
use anyhow::{Context, Error};
|
||||||
use gimli::write;
|
use gimli::write;
|
||||||
use gimli::{AttributeValue, DebuggingInformationEntry, Unit};
|
use gimli::{AttributeValue, DebuggingInformationEntry, Unit};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
@@ -356,7 +356,7 @@ where
|
|||||||
vmctx_die_id,
|
vmctx_die_id,
|
||||||
addr_tr,
|
addr_tr,
|
||||||
current_value_range.top(),
|
current_value_range.top(),
|
||||||
current_scope_ranges.top().expect("range"),
|
current_scope_ranges.top().context("range")?,
|
||||||
out_strings,
|
out_strings,
|
||||||
isa,
|
isa,
|
||||||
)?;
|
)?;
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ pub(crate) fn append_vmctx_info(
|
|||||||
let expr = CompiledExpression::vmctx(isa);
|
let expr = CompiledExpression::vmctx(isa);
|
||||||
let mut locs = Vec::new();
|
let mut locs = Vec::new();
|
||||||
for (begin, length, data) in
|
for (begin, length, data) in
|
||||||
expr.build_with_locals(scope_ranges, addr_tr, frame_info, endian)
|
expr.build_with_locals(scope_ranges, addr_tr, frame_info, endian)?
|
||||||
{
|
{
|
||||||
locs.push(write::Location::StartLength {
|
locs.push(write::Location::StartLength {
|
||||||
begin,
|
begin,
|
||||||
|
|||||||
@@ -71,7 +71,9 @@ impl<'data> RawCompiledModule<'data> {
|
|||||||
.map_err(|error| SetupError::Compile(CompileError::Wasm(error)))?;
|
.map_err(|error| SetupError::Compile(CompileError::Wasm(error)))?;
|
||||||
|
|
||||||
let debug_data = if debug_info {
|
let debug_data = if debug_info {
|
||||||
Some(read_debuginfo(&data))
|
// TODO Do we want to ignore invalid DWARF data?
|
||||||
|
let debug_data = read_debuginfo(&data)?;
|
||||||
|
Some(debug_data)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ pub fn compile_to_obj(
|
|||||||
.context("failed to emit module")?;
|
.context("failed to emit module")?;
|
||||||
|
|
||||||
if debug_info {
|
if debug_info {
|
||||||
let debug_data = read_debuginfo(wasm);
|
let debug_data = read_debuginfo(wasm).context("failed to emit DWARF")?;
|
||||||
emit_debugsections(
|
emit_debugsections(
|
||||||
&mut obj,
|
&mut obj,
|
||||||
&module_vmctx_info,
|
&module_vmctx_info,
|
||||||
|
|||||||
Reference in New Issue
Block a user