Skip to content

Commit 5d007d7

Browse files
authored
feat(wasm): support for wasm (#166)
1 parent 9dd0969 commit 5d007d7

File tree

18 files changed

+460
-20
lines changed

18 files changed

+460
-20
lines changed

symbolic-cabi/include/symbolic.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#ifndef SYMBOLIC_H_INCLUDED
44
#define SYMBOLIC_H_INCLUDED
55

6-
/* Generated with cbindgen:0.14.2 */
6+
/* Generated with cbindgen:0.14.3 */
77

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

@@ -33,6 +33,7 @@ enum SymbolicErrorCode {
3333
SYMBOLIC_ERROR_CODE_OBJECT_ERROR_BAD_PDB_OBJECT = 2105,
3434
SYMBOLIC_ERROR_CODE_OBJECT_ERROR_BAD_PE_OBJECT = 2106,
3535
SYMBOLIC_ERROR_CODE_OBJECT_ERROR_BAD_SOURCE_BUNDLE = 2107,
36+
SYMBOLIC_ERROR_CODE_OBJECT_ERROR_BAD_WASM_OBJECT = 2108,
3637
SYMBOLIC_ERROR_CODE_DWARF_ERROR_UNKNOWN = 2200,
3738
SYMBOLIC_ERROR_CODE_DWARF_ERROR_INVALID_UNIT_REF = 2201,
3839
SYMBOLIC_ERROR_CODE_DWARF_ERROR_INVALID_FILE_REF = 2202,

symbolic-cabi/src/core.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ pub enum SymbolicErrorCode {
159159
ObjectErrorBadPdbObject = 2105,
160160
ObjectErrorBadPeObject = 2106,
161161
ObjectErrorBadSourceBundle = 2107,
162+
ObjectErrorBadWasmObject = 2108,
162163
DwarfErrorUnknown = 2200,
163164
DwarfErrorInvalidUnitRef = 2201,
164165
DwarfErrorInvalidFileRef = 2202,
@@ -262,6 +263,7 @@ impl SymbolicErrorCode {
262263
ObjectError::MachO(_) => SymbolicErrorCode::ObjectErrorBadMachOObject,
263264
ObjectError::Pdb(_) => SymbolicErrorCode::ObjectErrorBadPdbObject,
264265
ObjectError::Pe(_) => SymbolicErrorCode::ObjectErrorBadPeObject,
266+
ObjectError::Wasm(_) => SymbolicErrorCode::ObjectErrorBadWasmObject,
265267
ObjectError::Dwarf(ref e) => match e {
266268
DwarfError::InvalidUnitRef(_) => {
267269
SymbolicErrorCode::DwarfErrorInvalidUnitRef

symbolic-common/src/types.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ pub enum CpuFamily {
9090
Mips64 = 8,
9191
/// ILP32 ABI on 64-bit ARM.
9292
Arm64_32 = 9,
93+
/// Virtual WASM architecture.
94+
Wasm = 10,
9395
}
9496

9597
impl CpuFamily {
@@ -111,6 +113,7 @@ impl CpuFamily {
111113
pub fn pointer_size(self) -> Option<usize> {
112114
match self {
113115
CpuFamily::Unknown => None,
116+
CpuFamily::Wasm => Some(4),
114117
CpuFamily::Amd64
115118
| CpuFamily::Arm64
116119
| CpuFamily::Ppc64
@@ -139,6 +142,7 @@ impl CpuFamily {
139142
/// ```
140143
pub fn instruction_alignment(self) -> Option<u64> {
141144
match self {
145+
CpuFamily::Wasm => Some(4),
142146
CpuFamily::Arm32 => Some(2),
143147
CpuFamily::Arm64 | CpuFamily::Arm64_32 => Some(4),
144148
CpuFamily::Ppc32 | CpuFamily::Mips32 | CpuFamily::Mips64 => Some(4),
@@ -174,6 +178,7 @@ impl CpuFamily {
174178
CpuFamily::Arm32 | CpuFamily::Arm64 | CpuFamily::Arm64_32 => Some("pc"),
175179
CpuFamily::Ppc32 | CpuFamily::Ppc64 => Some("srr0"),
176180
CpuFamily::Mips32 | CpuFamily::Mips64 => Some("pc"),
181+
CpuFamily::Wasm => None,
177182
CpuFamily::Unknown => None,
178183
}
179184
}
@@ -280,6 +285,7 @@ pub enum Arch {
280285
Arm64_32 = 901,
281286
Arm64_32V8 = 902,
282287
Arm64_32Unknown = 999,
288+
Wasm = 1001,
283289
}
284290

285291
impl Arch {
@@ -325,6 +331,7 @@ impl Arch {
325331
901 => Arch::Arm64_32,
326332
902 => Arch::Arm64_32V8,
327333
999 => Arch::Arm64_32Unknown,
334+
1001 => Arch::Wasm,
328335
_ => Arch::Unknown,
329336
}
330337
}
@@ -361,6 +368,7 @@ impl Arch {
361368
Arch::Mips => CpuFamily::Mips32,
362369
Arch::Mips64 => CpuFamily::Mips64,
363370
Arch::Arm64_32 | Arch::Arm64_32V8 | Arch::Arm64_32Unknown => CpuFamily::Arm64_32,
371+
Arch::Wasm => CpuFamily::Wasm,
364372
}
365373
}
366374

@@ -384,6 +392,7 @@ impl Arch {
384392
pub fn name(self) -> &'static str {
385393
match self {
386394
Arch::Unknown => "unknown",
395+
Arch::Wasm => "wasm",
387396
Arch::X86 => "x86",
388397
Arch::X86Unknown => "x86_unknown",
389398
Arch::Amd64 => "x86_64",
@@ -491,6 +500,9 @@ impl str::FromStr for Arch {
491500
"x86-64" => Arch::Amd64,
492501
"arm-64" => Arch::Arm64,
493502

503+
// wasm extensions
504+
"wasm" => Arch::Wasm,
505+
494506
_ => return Err(UnknownArchError),
495507
})
496508
}

symbolic-debuginfo/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ smallvec = "1.2.0"
4141
symbolic-common = { version = "7.5.0", path = "../symbolic-common" }
4242
thiserror = "1.0.20"
4343
zip = "0.5.2"
44+
walrus = "0.18.0"
45+
wasmparser = "0.68.0"
4446

4547
[dev-dependencies]
46-
insta = "1.1.0"
48+
insta = "1.3.0"
4749
symbolic-testutils = { path = "../symbolic-testutils" }

symbolic-debuginfo/src/base.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,8 @@ pub enum FileFormat {
156156
Pe,
157157
/// Source code bundle ZIP.
158158
SourceBundle,
159+
/// WASM container.
160+
Wasm,
159161
}
160162

161163
impl FileFormat {
@@ -169,6 +171,7 @@ impl FileFormat {
169171
FileFormat::Pdb => "pdb",
170172
FileFormat::Pe => "pe",
171173
FileFormat::SourceBundle => "sourcebundle",
174+
FileFormat::Wasm => "wasm",
172175
}
173176
}
174177
}
@@ -190,6 +193,7 @@ impl FromStr for FileFormat {
190193
"pdb" => FileFormat::Pdb,
191194
"pe" => FileFormat::Pe,
192195
"sourcebundle" => FileFormat::SourceBundle,
196+
"wasm" => FileFormat::Wasm,
193197
_ => return Err(UnknownFileFormatError),
194198
})
195199
}

symbolic-debuginfo/src/dwarf.rs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,14 @@ type IncompleteLineNumberProgram<'a> = gimli::read::IncompleteLineProgram<Slice<
4343
type LineNumberProgramHeader<'a> = gimli::read::LineProgramHeader<Slice<'a>>;
4444
type LineProgramFileEntry<'a> = gimli::read::FileEntry<Slice<'a>>;
4545

46+
/// This applies the offset to the address.
47+
///
48+
/// This function does not panic but would wrap around if too large or small
49+
/// numbers are passed.
50+
fn offset(addr: u64, offset: i64) -> u64 {
51+
(addr as i64).wrapping_sub(offset as i64) as u64
52+
}
53+
4654
/// An error handling [`DWARF`](trait.Dwarf.html) debugging information.
4755
#[non_exhaustive]
4856
#[derive(Debug, Error)]
@@ -536,7 +544,7 @@ impl<'d, 'a> DwarfUnit<'d, 'a> {
536544
if let Some((first, rows)) = rows.split_first() {
537545
let mut last_file = first.file_index;
538546
let mut last_info = LineInfo {
539-
address: range.begin - self.inner.info.load_address,
547+
address: offset(range.begin, self.inner.info.address_offset),
540548
size: first.size.map(|s| s + first.address - range.begin),
541549
file: self.resolve_file(first.file_index).unwrap_or_default(),
542550
line: first.line.unwrap_or(0),
@@ -560,7 +568,7 @@ impl<'d, 'a> DwarfUnit<'d, 'a> {
560568

561569
last_file = row.file_index;
562570
last_info = LineInfo {
563-
address: row.address - self.inner.info.load_address,
571+
address: offset(row.address, self.inner.info.address_offset),
564572
size: row.size,
565573
file: self.resolve_file(row.file_index).unwrap_or_default(),
566574
line,
@@ -569,7 +577,7 @@ impl<'d, 'a> DwarfUnit<'d, 'a> {
569577

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

575583
lines.push(last_info);
@@ -659,7 +667,7 @@ impl<'d, 'a> DwarfUnit<'d, 'a> {
659667
continue;
660668
}
661669

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

@@ -715,8 +723,8 @@ impl<'d, 'a> DwarfUnit<'d, 'a> {
715723

716724
let mut index = 0;
717725
for range in range_buf.iter() {
718-
let range_begin = range.begin - self.inner.info.load_address;
719-
let range_end = range.end - self.inner.info.load_address;
726+
let range_begin = offset(range.begin, self.inner.info.address_offset);
727+
let range_end = offset(range.end, self.inner.info.address_offset);
720728

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

@@ -969,7 +977,7 @@ impl<'d> DwarfInfo<'d> {
969977
pub fn parse(
970978
sections: &'d DwarfSections<'d>,
971979
symbol_map: SymbolMap<'d>,
972-
load_address: u64,
980+
address_offset: i64,
973981
kind: ObjectKind,
974982
) -> Result<Self, DwarfError> {
975983
let inner = gimli::read::Dwarf {
@@ -998,7 +1006,7 @@ impl<'d> DwarfInfo<'d> {
9981006
headers,
9991007
units,
10001008
symbol_map,
1001-
load_address,
1009+
address_offset,
10021010
kind,
10031011
})
10041012
}
@@ -1074,7 +1082,7 @@ impl fmt::Debug for DwarfInfo<'_> {
10741082
f.debug_struct("DwarfInfo")
10751083
.field("headers", &self.headers)
10761084
.field("symbol_map", &self.symbol_map)
1077-
.field("load_address", &self.load_address)
1085+
.field("address_offset", &self.address_offset)
10781086
.finish()
10791087
}
10801088
}
@@ -1122,15 +1130,15 @@ impl<'data> DwarfDebugSession<'data> {
11221130
pub fn parse<D>(
11231131
dwarf: &D,
11241132
symbol_map: SymbolMap<'data>,
1125-
load_address: u64,
1133+
address_offset: i64,
11261134
kind: ObjectKind,
11271135
) -> Result<Self, DwarfError>
11281136
where
11291137
D: Dwarf<'data>,
11301138
{
11311139
let sections = DwarfSections::from_dwarf(dwarf)?;
11321140
let cell = SelfCell::try_new(Box::new(sections), |sections| {
1133-
DwarfInfo::parse(unsafe { &*sections }, symbol_map, load_address, kind)
1141+
DwarfInfo::parse(unsafe { &*sections }, symbol_map, address_offset, kind)
11341142
})?;
11351143

11361144
Ok(DwarfDebugSession { cell })

symbolic-debuginfo/src/elf.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ impl<'data> ElfObject<'data> {
241241
/// [`has_debug_info`](struct.ElfObject.html#method.has_debug_info).
242242
pub fn debug_session(&self) -> Result<DwarfDebugSession<'data>, DwarfError> {
243243
let symbols = self.symbol_map();
244-
DwarfDebugSession::parse(self, symbols, self.load_address(), self.kind())
244+
DwarfDebugSession::parse(self, symbols, self.load_address() as i64, self.kind())
245245
}
246246

247247
/// Determines whether this object contains stack unwinding information.

symbolic-debuginfo/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ pub mod macho;
4646
pub mod pdb;
4747
pub mod pe;
4848
pub mod sourcebundle;
49+
pub mod wasm;
4950

5051
pub use crate::base::*;
5152
pub use crate::object::*;

symbolic-debuginfo/src/macho.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ impl<'d> MachObject<'d> {
217217
/// [`has_debug_info`](struct.MachObject.html#method.has_debug_info).
218218
pub fn debug_session(&self) -> Result<DwarfDebugSession<'d>, DwarfError> {
219219
let symbols = self.symbol_map();
220-
DwarfDebugSession::parse(self, symbols, self.load_address(), self.kind())
220+
DwarfDebugSession::parse(self, symbols, self.load_address() as i64, self.kind())
221221
}
222222

223223
/// Determines whether this object contains stack unwinding information.

0 commit comments

Comments
 (0)