Skip to content

Commit

Permalink
feat(wasm): support for wasm (#166)
Browse files Browse the repository at this point in the history
  • Loading branch information
mitsuhiko authored Nov 24, 2020
1 parent 9dd0969 commit 5d007d7
Show file tree
Hide file tree
Showing 18 changed files with 460 additions and 20 deletions.
3 changes: 2 additions & 1 deletion symbolic-cabi/include/symbolic.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#ifndef SYMBOLIC_H_INCLUDED
#define SYMBOLIC_H_INCLUDED

/* Generated with cbindgen:0.14.2 */
/* Generated with cbindgen:0.14.3 */

/* Warning, this file is autogenerated. Do not modify this manually. */

Expand Down Expand Up @@ -33,6 +33,7 @@ enum SymbolicErrorCode {
SYMBOLIC_ERROR_CODE_OBJECT_ERROR_BAD_PDB_OBJECT = 2105,
SYMBOLIC_ERROR_CODE_OBJECT_ERROR_BAD_PE_OBJECT = 2106,
SYMBOLIC_ERROR_CODE_OBJECT_ERROR_BAD_SOURCE_BUNDLE = 2107,
SYMBOLIC_ERROR_CODE_OBJECT_ERROR_BAD_WASM_OBJECT = 2108,
SYMBOLIC_ERROR_CODE_DWARF_ERROR_UNKNOWN = 2200,
SYMBOLIC_ERROR_CODE_DWARF_ERROR_INVALID_UNIT_REF = 2201,
SYMBOLIC_ERROR_CODE_DWARF_ERROR_INVALID_FILE_REF = 2202,
Expand Down
2 changes: 2 additions & 0 deletions symbolic-cabi/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ pub enum SymbolicErrorCode {
ObjectErrorBadPdbObject = 2105,
ObjectErrorBadPeObject = 2106,
ObjectErrorBadSourceBundle = 2107,
ObjectErrorBadWasmObject = 2108,
DwarfErrorUnknown = 2200,
DwarfErrorInvalidUnitRef = 2201,
DwarfErrorInvalidFileRef = 2202,
Expand Down Expand Up @@ -262,6 +263,7 @@ impl SymbolicErrorCode {
ObjectError::MachO(_) => SymbolicErrorCode::ObjectErrorBadMachOObject,
ObjectError::Pdb(_) => SymbolicErrorCode::ObjectErrorBadPdbObject,
ObjectError::Pe(_) => SymbolicErrorCode::ObjectErrorBadPeObject,
ObjectError::Wasm(_) => SymbolicErrorCode::ObjectErrorBadWasmObject,
ObjectError::Dwarf(ref e) => match e {
DwarfError::InvalidUnitRef(_) => {
SymbolicErrorCode::DwarfErrorInvalidUnitRef
Expand Down
12 changes: 12 additions & 0 deletions symbolic-common/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ pub enum CpuFamily {
Mips64 = 8,
/// ILP32 ABI on 64-bit ARM.
Arm64_32 = 9,
/// Virtual WASM architecture.
Wasm = 10,
}

impl CpuFamily {
Expand All @@ -111,6 +113,7 @@ impl CpuFamily {
pub fn pointer_size(self) -> Option<usize> {
match self {
CpuFamily::Unknown => None,
CpuFamily::Wasm => Some(4),
CpuFamily::Amd64
| CpuFamily::Arm64
| CpuFamily::Ppc64
Expand Down Expand Up @@ -139,6 +142,7 @@ impl CpuFamily {
/// ```
pub fn instruction_alignment(self) -> Option<u64> {
match self {
CpuFamily::Wasm => Some(4),
CpuFamily::Arm32 => Some(2),
CpuFamily::Arm64 | CpuFamily::Arm64_32 => Some(4),
CpuFamily::Ppc32 | CpuFamily::Mips32 | CpuFamily::Mips64 => Some(4),
Expand Down Expand Up @@ -174,6 +178,7 @@ impl CpuFamily {
CpuFamily::Arm32 | CpuFamily::Arm64 | CpuFamily::Arm64_32 => Some("pc"),
CpuFamily::Ppc32 | CpuFamily::Ppc64 => Some("srr0"),
CpuFamily::Mips32 | CpuFamily::Mips64 => Some("pc"),
CpuFamily::Wasm => None,
CpuFamily::Unknown => None,
}
}
Expand Down Expand Up @@ -280,6 +285,7 @@ pub enum Arch {
Arm64_32 = 901,
Arm64_32V8 = 902,
Arm64_32Unknown = 999,
Wasm = 1001,
}

impl Arch {
Expand Down Expand Up @@ -325,6 +331,7 @@ impl Arch {
901 => Arch::Arm64_32,
902 => Arch::Arm64_32V8,
999 => Arch::Arm64_32Unknown,
1001 => Arch::Wasm,
_ => Arch::Unknown,
}
}
Expand Down Expand Up @@ -361,6 +368,7 @@ impl Arch {
Arch::Mips => CpuFamily::Mips32,
Arch::Mips64 => CpuFamily::Mips64,
Arch::Arm64_32 | Arch::Arm64_32V8 | Arch::Arm64_32Unknown => CpuFamily::Arm64_32,
Arch::Wasm => CpuFamily::Wasm,
}
}

Expand All @@ -384,6 +392,7 @@ impl Arch {
pub fn name(self) -> &'static str {
match self {
Arch::Unknown => "unknown",
Arch::Wasm => "wasm",
Arch::X86 => "x86",
Arch::X86Unknown => "x86_unknown",
Arch::Amd64 => "x86_64",
Expand Down Expand Up @@ -491,6 +500,9 @@ impl str::FromStr for Arch {
"x86-64" => Arch::Amd64,
"arm-64" => Arch::Arm64,

// wasm extensions
"wasm" => Arch::Wasm,

_ => return Err(UnknownArchError),
})
}
Expand Down
4 changes: 3 additions & 1 deletion symbolic-debuginfo/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ smallvec = "1.2.0"
symbolic-common = { version = "7.5.0", path = "../symbolic-common" }
thiserror = "1.0.20"
zip = "0.5.2"
walrus = "0.18.0"
wasmparser = "0.68.0"

[dev-dependencies]
insta = "1.1.0"
insta = "1.3.0"
symbolic-testutils = { path = "../symbolic-testutils" }
4 changes: 4 additions & 0 deletions symbolic-debuginfo/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ pub enum FileFormat {
Pe,
/// Source code bundle ZIP.
SourceBundle,
/// WASM container.
Wasm,
}

impl FileFormat {
Expand All @@ -169,6 +171,7 @@ impl FileFormat {
FileFormat::Pdb => "pdb",
FileFormat::Pe => "pe",
FileFormat::SourceBundle => "sourcebundle",
FileFormat::Wasm => "wasm",
}
}
}
Expand All @@ -190,6 +193,7 @@ impl FromStr for FileFormat {
"pdb" => FileFormat::Pdb,
"pe" => FileFormat::Pe,
"sourcebundle" => FileFormat::SourceBundle,
"wasm" => FileFormat::Wasm,
_ => return Err(UnknownFileFormatError),
})
}
Expand Down
32 changes: 20 additions & 12 deletions symbolic-debuginfo/src/dwarf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ type IncompleteLineNumberProgram<'a> = gimli::read::IncompleteLineProgram<Slice<
type LineNumberProgramHeader<'a> = gimli::read::LineProgramHeader<Slice<'a>>;
type LineProgramFileEntry<'a> = gimli::read::FileEntry<Slice<'a>>;

/// This applies the offset to the address.
///
/// This function does not panic but would wrap around if too large or small
/// numbers are passed.
fn offset(addr: u64, offset: i64) -> u64 {
(addr as i64).wrapping_sub(offset as i64) as u64
}

/// An error handling [`DWARF`](trait.Dwarf.html) debugging information.
#[non_exhaustive]
#[derive(Debug, Error)]
Expand Down Expand Up @@ -536,7 +544,7 @@ impl<'d, 'a> DwarfUnit<'d, 'a> {
if let Some((first, rows)) = rows.split_first() {
let mut last_file = first.file_index;
let mut last_info = LineInfo {
address: range.begin - self.inner.info.load_address,
address: offset(range.begin, self.inner.info.address_offset),
size: first.size.map(|s| s + first.address - range.begin),
file: self.resolve_file(first.file_index).unwrap_or_default(),
line: first.line.unwrap_or(0),
Expand All @@ -560,7 +568,7 @@ impl<'d, 'a> DwarfUnit<'d, 'a> {

last_file = row.file_index;
last_info = LineInfo {
address: row.address - self.inner.info.load_address,
address: offset(row.address, self.inner.info.address_offset),
size: row.size,
file: self.resolve_file(row.file_index).unwrap_or_default(),
line,
Expand All @@ -569,7 +577,7 @@ impl<'d, 'a> DwarfUnit<'d, 'a> {

// Fix the size of the last line
if let Some(size) = last_info.size.as_mut() {
*size = range.end - self.inner.info.load_address - last_info.address;
*size = offset(range.end, self.inner.info.address_offset) - last_info.address;
}

lines.push(last_info);
Expand Down Expand Up @@ -659,7 +667,7 @@ impl<'d, 'a> DwarfUnit<'d, 'a> {
continue;
}

let function_address = range_buf[0].begin - self.inner.info.load_address;
let function_address = offset(range_buf[0].begin, self.inner.info.address_offset);
let function_size = range_buf[range_buf.len() - 1].end - range_buf[0].begin;
let function_end = function_address + function_size;

Expand Down Expand Up @@ -715,8 +723,8 @@ impl<'d, 'a> DwarfUnit<'d, 'a> {

let mut index = 0;
for range in range_buf.iter() {
let range_begin = range.begin - self.inner.info.load_address;
let range_end = range.end - self.inner.info.load_address;
let range_begin = offset(range.begin, self.inner.info.address_offset);
let range_end = offset(range.end, self.inner.info.address_offset);

// Check if there is a line record covering the start of this range,
// otherwise insert a new record pointing to the correct call location.
Expand Down Expand Up @@ -952,7 +960,7 @@ struct DwarfInfo<'data> {
headers: Vec<CompilationUnitHeader<'data>>,
units: Vec<LazyCell<Option<Unit<'data>>>>,
symbol_map: SymbolMap<'data>,
load_address: u64,
address_offset: i64,
kind: ObjectKind,
}

Expand All @@ -969,7 +977,7 @@ impl<'d> DwarfInfo<'d> {
pub fn parse(
sections: &'d DwarfSections<'d>,
symbol_map: SymbolMap<'d>,
load_address: u64,
address_offset: i64,
kind: ObjectKind,
) -> Result<Self, DwarfError> {
let inner = gimli::read::Dwarf {
Expand Down Expand Up @@ -998,7 +1006,7 @@ impl<'d> DwarfInfo<'d> {
headers,
units,
symbol_map,
load_address,
address_offset,
kind,
})
}
Expand Down Expand Up @@ -1074,7 +1082,7 @@ impl fmt::Debug for DwarfInfo<'_> {
f.debug_struct("DwarfInfo")
.field("headers", &self.headers)
.field("symbol_map", &self.symbol_map)
.field("load_address", &self.load_address)
.field("address_offset", &self.address_offset)
.finish()
}
}
Expand Down Expand Up @@ -1122,15 +1130,15 @@ impl<'data> DwarfDebugSession<'data> {
pub fn parse<D>(
dwarf: &D,
symbol_map: SymbolMap<'data>,
load_address: u64,
address_offset: i64,
kind: ObjectKind,
) -> Result<Self, DwarfError>
where
D: Dwarf<'data>,
{
let sections = DwarfSections::from_dwarf(dwarf)?;
let cell = SelfCell::try_new(Box::new(sections), |sections| {
DwarfInfo::parse(unsafe { &*sections }, symbol_map, load_address, kind)
DwarfInfo::parse(unsafe { &*sections }, symbol_map, address_offset, kind)
})?;

Ok(DwarfDebugSession { cell })
Expand Down
2 changes: 1 addition & 1 deletion symbolic-debuginfo/src/elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ impl<'data> ElfObject<'data> {
/// [`has_debug_info`](struct.ElfObject.html#method.has_debug_info).
pub fn debug_session(&self) -> Result<DwarfDebugSession<'data>, DwarfError> {
let symbols = self.symbol_map();
DwarfDebugSession::parse(self, symbols, self.load_address(), self.kind())
DwarfDebugSession::parse(self, symbols, self.load_address() as i64, self.kind())
}

/// Determines whether this object contains stack unwinding information.
Expand Down
1 change: 1 addition & 0 deletions symbolic-debuginfo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ pub mod macho;
pub mod pdb;
pub mod pe;
pub mod sourcebundle;
pub mod wasm;

pub use crate::base::*;
pub use crate::object::*;
2 changes: 1 addition & 1 deletion symbolic-debuginfo/src/macho.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ impl<'d> MachObject<'d> {
/// [`has_debug_info`](struct.MachObject.html#method.has_debug_info).
pub fn debug_session(&self) -> Result<DwarfDebugSession<'d>, DwarfError> {
let symbols = self.symbol_map();
DwarfDebugSession::parse(self, symbols, self.load_address(), self.kind())
DwarfDebugSession::parse(self, symbols, self.load_address() as i64, self.kind())
}

/// Determines whether this object contains stack unwinding information.
Expand Down
Loading

0 comments on commit 5d007d7

Please sign in to comment.