std: dwarf namespace reorg
std.debug.Dwarf is the parsing/decoding logic. std.dwarf remains the unopinionated types and bits alone. If you look at this diff you can see a lot less redundancy in namespaces.
This commit is contained in:
@@ -18,6 +18,8 @@ const native_arch = builtin.cpu.arch;
|
||||
const native_os = builtin.os.tag;
|
||||
const native_endian = native_arch.endian();
|
||||
|
||||
pub const Dwarf = @import("debug/Dwarf.zig");
|
||||
|
||||
pub const runtime_safety = switch (builtin.mode) {
|
||||
.Debug, .ReleaseSafe => true,
|
||||
.ReleaseFast, .ReleaseSmall => false,
|
||||
@@ -67,7 +69,7 @@ pub const SymbolInfo = struct {
|
||||
};
|
||||
const PdbOrDwarf = union(enum) {
|
||||
pdb: pdb.Pdb,
|
||||
dwarf: DW.DwarfInfo,
|
||||
dwarf: Dwarf,
|
||||
|
||||
fn deinit(self: *PdbOrDwarf, allocator: mem.Allocator) void {
|
||||
switch (self.*) {
|
||||
@@ -566,7 +568,7 @@ pub const StackIterator = struct {
|
||||
// using DWARF and MachO unwind info.
|
||||
unwind_state: if (have_ucontext) ?struct {
|
||||
debug_info: *Info,
|
||||
dwarf_context: DW.UnwindContext,
|
||||
dwarf_context: Dwarf.UnwindContext,
|
||||
last_error: ?UnwindError = null,
|
||||
failed: bool = false,
|
||||
} else void = if (have_ucontext) null else {},
|
||||
@@ -599,7 +601,7 @@ pub const StackIterator = struct {
|
||||
var iterator = init(first_address, null);
|
||||
iterator.unwind_state = .{
|
||||
.debug_info = debug_info,
|
||||
.dwarf_context = try DW.UnwindContext.init(debug_info.allocator, context),
|
||||
.dwarf_context = try Dwarf.UnwindContext.init(debug_info.allocator, context),
|
||||
};
|
||||
|
||||
return iterator;
|
||||
@@ -783,7 +785,7 @@ pub const StackIterator = struct {
|
||||
// __unwind_info is a requirement for unwinding on Darwin. It may fall back to DWARF, but unwinding
|
||||
// via DWARF before attempting to use the compact unwind info will produce incorrect results.
|
||||
if (module.unwind_info) |unwind_info| {
|
||||
if (DW.unwindFrameMachO(&unwind_state.dwarf_context, &it.ma, unwind_info, module.eh_frame, module.base_address)) |return_address| {
|
||||
if (Dwarf.unwindFrameMachO(&unwind_state.dwarf_context, &it.ma, unwind_info, module.eh_frame, module.base_address)) |return_address| {
|
||||
return return_address;
|
||||
} else |err| {
|
||||
if (err != error.RequiresDWARFUnwind) return err;
|
||||
@@ -1140,10 +1142,10 @@ fn readCoffDebugInfo(allocator: mem.Allocator, coff_obj: *coff.Coff) !ModuleDebu
|
||||
|
||||
if (coff_obj.getSectionByName(".debug_info")) |_| {
|
||||
// This coff file has embedded DWARF debug info
|
||||
var sections: DW.DwarfInfo.SectionArray = DW.DwarfInfo.null_section_array;
|
||||
var sections: Dwarf.SectionArray = Dwarf.null_section_array;
|
||||
errdefer for (sections) |section| if (section) |s| if (s.owned) allocator.free(s.data);
|
||||
|
||||
inline for (@typeInfo(DW.DwarfSection).Enum.fields, 0..) |section, i| {
|
||||
inline for (@typeInfo(Dwarf.Section.Id).Enum.fields, 0..) |section, i| {
|
||||
sections[i] = if (coff_obj.getSectionByName("." ++ section.name)) |section_header| blk: {
|
||||
break :blk .{
|
||||
.data = try coff_obj.getSectionDataAlloc(section_header, allocator),
|
||||
@@ -1153,13 +1155,13 @@ fn readCoffDebugInfo(allocator: mem.Allocator, coff_obj: *coff.Coff) !ModuleDebu
|
||||
} else null;
|
||||
}
|
||||
|
||||
var dwarf = DW.DwarfInfo{
|
||||
var dwarf = Dwarf{
|
||||
.endian = native_endian,
|
||||
.sections = sections,
|
||||
.is_macho = false,
|
||||
};
|
||||
|
||||
try DW.openDwarfDebugInfo(&dwarf, allocator);
|
||||
try Dwarf.open(&dwarf, allocator);
|
||||
di.dwarf = dwarf;
|
||||
}
|
||||
|
||||
@@ -1211,7 +1213,7 @@ pub fn readElfDebugInfo(
|
||||
elf_filename: ?[]const u8,
|
||||
build_id: ?[]const u8,
|
||||
expected_crc: ?u32,
|
||||
parent_sections: *DW.DwarfInfo.SectionArray,
|
||||
parent_sections: *Dwarf.SectionArray,
|
||||
parent_mapped_mem: ?[]align(mem.page_size) const u8,
|
||||
) !ModuleDebugInfo {
|
||||
nosuspend {
|
||||
@@ -1245,7 +1247,7 @@ pub fn readElfDebugInfo(
|
||||
@ptrCast(@alignCast(&mapped_mem[shoff])),
|
||||
)[0..hdr.e_shnum];
|
||||
|
||||
var sections: DW.DwarfInfo.SectionArray = DW.DwarfInfo.null_section_array;
|
||||
var sections: Dwarf.SectionArray = Dwarf.null_section_array;
|
||||
|
||||
// Combine section list. This takes ownership over any owned sections from the parent scope.
|
||||
for (parent_sections, §ions) |*parent, *section| {
|
||||
@@ -1274,7 +1276,7 @@ pub fn readElfDebugInfo(
|
||||
}
|
||||
|
||||
var section_index: ?usize = null;
|
||||
inline for (@typeInfo(DW.DwarfSection).Enum.fields, 0..) |section, i| {
|
||||
inline for (@typeInfo(Dwarf.Section.Id).Enum.fields, 0..) |section, i| {
|
||||
if (mem.eql(u8, "." ++ section.name, name)) section_index = i;
|
||||
}
|
||||
if (section_index == null) continue;
|
||||
@@ -1308,10 +1310,10 @@ pub fn readElfDebugInfo(
|
||||
}
|
||||
|
||||
const missing_debug_info =
|
||||
sections[@intFromEnum(DW.DwarfSection.debug_info)] == null or
|
||||
sections[@intFromEnum(DW.DwarfSection.debug_abbrev)] == null or
|
||||
sections[@intFromEnum(DW.DwarfSection.debug_str)] == null or
|
||||
sections[@intFromEnum(DW.DwarfSection.debug_line)] == null;
|
||||
sections[@intFromEnum(Dwarf.Section.Id.debug_info)] == null or
|
||||
sections[@intFromEnum(Dwarf.Section.Id.debug_abbrev)] == null or
|
||||
sections[@intFromEnum(Dwarf.Section.Id.debug_str)] == null or
|
||||
sections[@intFromEnum(Dwarf.Section.Id.debug_line)] == null;
|
||||
|
||||
// Attempt to load debug info from an external file
|
||||
// See: https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html
|
||||
@@ -1379,13 +1381,13 @@ pub fn readElfDebugInfo(
|
||||
return error.MissingDebugInfo;
|
||||
}
|
||||
|
||||
var di = DW.DwarfInfo{
|
||||
var di = Dwarf{
|
||||
.endian = endian,
|
||||
.sections = sections,
|
||||
.is_macho = false,
|
||||
};
|
||||
|
||||
try DW.openDwarfDebugInfo(&di, allocator);
|
||||
try Dwarf.open(&di, allocator);
|
||||
|
||||
return ModuleDebugInfo{
|
||||
.base_address = undefined,
|
||||
@@ -2168,13 +2170,13 @@ pub const Info = struct {
|
||||
const obj_di = try self.allocator.create(ModuleDebugInfo);
|
||||
errdefer self.allocator.destroy(obj_di);
|
||||
|
||||
var sections: DW.DwarfInfo.SectionArray = DW.DwarfInfo.null_section_array;
|
||||
var sections: Dwarf.SectionArray = Dwarf.null_section_array;
|
||||
if (ctx.gnu_eh_frame) |eh_frame_hdr| {
|
||||
// This is a special case - pointer offsets inside .eh_frame_hdr
|
||||
// are encoded relative to its base address, so we must use the
|
||||
// version that is already memory mapped, and not the one that
|
||||
// will be mapped separately from the ELF file.
|
||||
sections[@intFromEnum(DW.DwarfSection.eh_frame_hdr)] = .{
|
||||
sections[@intFromEnum(Dwarf.Section.Id.eh_frame_hdr)] = .{
|
||||
.data = eh_frame_hdr,
|
||||
.owned = false,
|
||||
};
|
||||
@@ -2219,7 +2221,7 @@ pub const ModuleDebugInfo = switch (native_os) {
|
||||
|
||||
const OFileTable = std.StringHashMap(OFileInfo);
|
||||
const OFileInfo = struct {
|
||||
di: DW.DwarfInfo,
|
||||
di: Dwarf,
|
||||
addr_table: std.StringHashMap(u64),
|
||||
};
|
||||
|
||||
@@ -2278,8 +2280,8 @@ pub const ModuleDebugInfo = switch (native_os) {
|
||||
addr_table.putAssumeCapacityNoClobber(sym_name, sym.n_value);
|
||||
}
|
||||
|
||||
var sections: DW.DwarfInfo.SectionArray = DW.DwarfInfo.null_section_array;
|
||||
if (self.eh_frame) |eh_frame| sections[@intFromEnum(DW.DwarfSection.eh_frame)] = .{
|
||||
var sections: Dwarf.SectionArray = Dwarf.null_section_array;
|
||||
if (self.eh_frame) |eh_frame| sections[@intFromEnum(Dwarf.Section.Id.eh_frame)] = .{
|
||||
.data = eh_frame,
|
||||
.owned = false,
|
||||
};
|
||||
@@ -2288,7 +2290,7 @@ pub const ModuleDebugInfo = switch (native_os) {
|
||||
if (!std.mem.eql(u8, "__DWARF", sect.segName())) continue;
|
||||
|
||||
var section_index: ?usize = null;
|
||||
inline for (@typeInfo(DW.DwarfSection).Enum.fields, 0..) |section, i| {
|
||||
inline for (@typeInfo(Dwarf.Section.Id).Enum.fields, 0..) |section, i| {
|
||||
if (mem.eql(u8, "__" ++ section.name, sect.sectName())) section_index = i;
|
||||
}
|
||||
if (section_index == null) continue;
|
||||
@@ -2302,19 +2304,19 @@ pub const ModuleDebugInfo = switch (native_os) {
|
||||
}
|
||||
|
||||
const missing_debug_info =
|
||||
sections[@intFromEnum(DW.DwarfSection.debug_info)] == null or
|
||||
sections[@intFromEnum(DW.DwarfSection.debug_abbrev)] == null or
|
||||
sections[@intFromEnum(DW.DwarfSection.debug_str)] == null or
|
||||
sections[@intFromEnum(DW.DwarfSection.debug_line)] == null;
|
||||
sections[@intFromEnum(Dwarf.Section.Id.debug_info)] == null or
|
||||
sections[@intFromEnum(Dwarf.Section.Id.debug_abbrev)] == null or
|
||||
sections[@intFromEnum(Dwarf.Section.Id.debug_str)] == null or
|
||||
sections[@intFromEnum(Dwarf.Section.Id.debug_line)] == null;
|
||||
if (missing_debug_info) return error.MissingDebugInfo;
|
||||
|
||||
var di = DW.DwarfInfo{
|
||||
var di = Dwarf{
|
||||
.endian = .little,
|
||||
.sections = sections,
|
||||
.is_macho = true,
|
||||
};
|
||||
|
||||
try DW.openDwarfDebugInfo(&di, allocator);
|
||||
try Dwarf.open(&di, allocator);
|
||||
const info = OFileInfo{
|
||||
.di = di,
|
||||
.addr_table = addr_table,
|
||||
@@ -2411,14 +2413,14 @@ pub const ModuleDebugInfo = switch (native_os) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn getDwarfInfoForAddress(self: *@This(), allocator: mem.Allocator, address: usize) !?*const DW.DwarfInfo {
|
||||
pub fn getDwarfInfoForAddress(self: *@This(), allocator: mem.Allocator, address: usize) !?*const Dwarf {
|
||||
return if ((try self.getOFileInfoForAddress(allocator, address)).o_file_info) |o_file_info| &o_file_info.di else null;
|
||||
}
|
||||
},
|
||||
.uefi, .windows => struct {
|
||||
base_address: usize,
|
||||
pdb: ?pdb.Pdb = null,
|
||||
dwarf: ?DW.DwarfInfo = null,
|
||||
dwarf: ?Dwarf = null,
|
||||
coff_image_base: u64,
|
||||
|
||||
/// Only used if pdb is non-null
|
||||
@@ -2488,7 +2490,7 @@ pub const ModuleDebugInfo = switch (native_os) {
|
||||
return SymbolInfo{};
|
||||
}
|
||||
|
||||
pub fn getDwarfInfoForAddress(self: *@This(), allocator: mem.Allocator, address: usize) !?*const DW.DwarfInfo {
|
||||
pub fn getDwarfInfoForAddress(self: *@This(), allocator: mem.Allocator, address: usize) !?*const Dwarf {
|
||||
_ = allocator;
|
||||
_ = address;
|
||||
|
||||
@@ -2500,7 +2502,7 @@ pub const ModuleDebugInfo = switch (native_os) {
|
||||
},
|
||||
.linux, .netbsd, .freebsd, .dragonfly, .openbsd, .haiku, .solaris, .illumos => struct {
|
||||
base_address: usize,
|
||||
dwarf: DW.DwarfInfo,
|
||||
dwarf: Dwarf,
|
||||
mapped_memory: []align(mem.page_size) const u8,
|
||||
external_mapped_memory: ?[]align(mem.page_size) const u8,
|
||||
|
||||
@@ -2516,7 +2518,7 @@ pub const ModuleDebugInfo = switch (native_os) {
|
||||
return getSymbolFromDwarf(allocator, relocated_address, &self.dwarf);
|
||||
}
|
||||
|
||||
pub fn getDwarfInfoForAddress(self: *@This(), allocator: mem.Allocator, address: usize) !?*const DW.DwarfInfo {
|
||||
pub fn getDwarfInfoForAddress(self: *@This(), allocator: mem.Allocator, address: usize) !?*const Dwarf {
|
||||
_ = allocator;
|
||||
_ = address;
|
||||
return &self.dwarf;
|
||||
@@ -2535,17 +2537,17 @@ pub const ModuleDebugInfo = switch (native_os) {
|
||||
return SymbolInfo{};
|
||||
}
|
||||
|
||||
pub fn getDwarfInfoForAddress(self: *@This(), allocator: mem.Allocator, address: usize) !?*const DW.DwarfInfo {
|
||||
pub fn getDwarfInfoForAddress(self: *@This(), allocator: mem.Allocator, address: usize) !?*const Dwarf {
|
||||
_ = self;
|
||||
_ = allocator;
|
||||
_ = address;
|
||||
return null;
|
||||
}
|
||||
},
|
||||
else => DW.DwarfInfo,
|
||||
else => Dwarf,
|
||||
};
|
||||
|
||||
fn getSymbolFromDwarf(allocator: mem.Allocator, address: u64, di: *DW.DwarfInfo) !SymbolInfo {
|
||||
fn getSymbolFromDwarf(allocator: mem.Allocator, address: u64, di: *Dwarf) !SymbolInfo {
|
||||
if (nosuspend di.findCompileUnit(address)) |compile_unit| {
|
||||
return SymbolInfo{
|
||||
.symbol_name = nosuspend di.getSymbolName(address) orelse "???",
|
||||
|
||||
2709
lib/std/debug/Dwarf.zig
Normal file
2709
lib/std/debug/Dwarf.zig
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
const builtin = @import("builtin");
|
||||
const std = @import("../std.zig");
|
||||
const std = @import("../../std.zig");
|
||||
const mem = std.mem;
|
||||
const native_os = builtin.os.tag;
|
||||
const posix = std.posix;
|
||||
@@ -392,7 +392,7 @@ pub fn regBytes(
|
||||
/// Returns the ABI-defined default value this register has in the unwinding table
|
||||
/// before running any of the CIE instructions. The DWARF spec defines these as having
|
||||
/// the .undefined rule by default, but allows ABI authors to override that.
|
||||
pub fn getRegDefaultValue(reg_number: u8, context: *std.dwarf.UnwindContext, out: []u8) !void {
|
||||
pub fn getRegDefaultValue(reg_number: u8, context: *std.debug.Dwarf.UnwindContext, out: []u8) !void {
|
||||
switch (builtin.cpu.arch) {
|
||||
.aarch64 => {
|
||||
// Callee-saved registers are initialized as if they had the .same_value rule
|
||||
@@ -1,14 +1,14 @@
|
||||
const builtin = @import("builtin");
|
||||
const std = @import("../std.zig");
|
||||
const std = @import("../../std.zig");
|
||||
const mem = std.mem;
|
||||
const debug = std.debug;
|
||||
const leb = std.leb;
|
||||
const dwarf = std.dwarf;
|
||||
const abi = dwarf.abi;
|
||||
const expressions = dwarf.expressions;
|
||||
const DW = std.dwarf;
|
||||
const abi = std.debug.Dwarf.abi;
|
||||
const assert = std.debug.assert;
|
||||
const native_endian = builtin.cpu.arch.endian();
|
||||
|
||||
/// TODO merge with std.dwarf.CFA
|
||||
const Opcode = enum(u8) {
|
||||
advance_loc = 0x1 << 6,
|
||||
offset = 0x2 << 6,
|
||||
@@ -363,8 +363,8 @@ pub const VirtualMachine = struct {
|
||||
/// Resolves the register rule and places the result into `out` (see dwarf.abi.regBytes)
|
||||
pub fn resolveValue(
|
||||
self: Column,
|
||||
context: *dwarf.UnwindContext,
|
||||
expression_context: dwarf.expressions.ExpressionContext,
|
||||
context: *std.debug.Dwarf.UnwindContext,
|
||||
expression_context: std.debug.Dwarf.expression.Context,
|
||||
ma: *debug.StackIterator.MemoryAccessor,
|
||||
out: []u8,
|
||||
) !void {
|
||||
@@ -483,8 +483,8 @@ pub const VirtualMachine = struct {
|
||||
self: *VirtualMachine,
|
||||
allocator: std.mem.Allocator,
|
||||
pc: u64,
|
||||
cie: dwarf.CommonInformationEntry,
|
||||
fde: dwarf.FrameDescriptionEntry,
|
||||
cie: std.debug.Dwarf.CommonInformationEntry,
|
||||
fde: std.debug.Dwarf.FrameDescriptionEntry,
|
||||
addr_size_bytes: u8,
|
||||
endian: std.builtin.Endian,
|
||||
) !Row {
|
||||
@@ -502,7 +502,7 @@ pub const VirtualMachine = struct {
|
||||
|
||||
for (&streams, 0..) |stream, i| {
|
||||
while (stream.pos < stream.buffer.len) {
|
||||
const instruction = try dwarf.call_frame.Instruction.read(stream, addr_size_bytes, endian);
|
||||
const instruction = try std.debug.Dwarf.call_frame.Instruction.read(stream, addr_size_bytes, endian);
|
||||
prev_row = try self.step(allocator, cie, i == 0, instruction);
|
||||
if (pc < fde.pc_begin + self.current_row.offset) return prev_row;
|
||||
}
|
||||
@@ -515,8 +515,8 @@ pub const VirtualMachine = struct {
|
||||
self: *VirtualMachine,
|
||||
allocator: std.mem.Allocator,
|
||||
pc: u64,
|
||||
cie: dwarf.CommonInformationEntry,
|
||||
fde: dwarf.FrameDescriptionEntry,
|
||||
cie: std.debug.Dwarf.CommonInformationEntry,
|
||||
fde: std.debug.Dwarf.FrameDescriptionEntry,
|
||||
) !Row {
|
||||
return self.runTo(allocator, pc, cie, fde, @sizeOf(usize), builtin.target.cpu.arch.endian());
|
||||
}
|
||||
@@ -538,7 +538,7 @@ pub const VirtualMachine = struct {
|
||||
pub fn step(
|
||||
self: *VirtualMachine,
|
||||
allocator: std.mem.Allocator,
|
||||
cie: dwarf.CommonInformationEntry,
|
||||
cie: std.debug.Dwarf.CommonInformationEntry,
|
||||
is_initial: bool,
|
||||
instruction: Instruction,
|
||||
) !Row {
|
||||
@@ -1,9 +1,8 @@
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const OP = @import("OP.zig");
|
||||
const leb = std.leb;
|
||||
const dwarf = std.dwarf;
|
||||
const abi = dwarf.abi;
|
||||
const OP = std.dwarf.OP;
|
||||
const abi = std.debug.Dwarf.abi;
|
||||
const mem = std.mem;
|
||||
const assert = std.debug.assert;
|
||||
const native_endian = builtin.cpu.arch.endian();
|
||||
@@ -11,46 +10,37 @@ const native_endian = builtin.cpu.arch.endian();
|
||||
/// Expressions can be evaluated in different contexts, each requiring its own set of inputs.
|
||||
/// Callers should specify all the fields relevant to their context. If a field is required
|
||||
/// by the expression and it isn't in the context, error.IncompleteExpressionContext is returned.
|
||||
pub const ExpressionContext = struct {
|
||||
pub const Context = struct {
|
||||
/// The dwarf format of the section this expression is in
|
||||
format: dwarf.Format = .@"32",
|
||||
|
||||
format: std.dwarf.Format = .@"32",
|
||||
/// If specified, any addresses will pass through before being accessed
|
||||
memory_accessor: ?*std.debug.StackIterator.MemoryAccessor = null,
|
||||
|
||||
/// The compilation unit this expression relates to, if any
|
||||
compile_unit: ?*const dwarf.CompileUnit = null,
|
||||
|
||||
compile_unit: ?*const std.debug.Dwarf.CompileUnit = null,
|
||||
/// When evaluating a user-presented expression, this is the address of the object being evaluated
|
||||
object_address: ?*const anyopaque = null,
|
||||
|
||||
/// .debug_addr section
|
||||
debug_addr: ?[]const u8 = null,
|
||||
|
||||
/// Thread context
|
||||
thread_context: ?*std.debug.ThreadContext = null,
|
||||
reg_context: ?abi.RegisterContext = null,
|
||||
|
||||
/// Call frame address, if in a CFI context
|
||||
cfa: ?usize = null,
|
||||
|
||||
/// This expression is a sub-expression from an OP.entry_value instruction
|
||||
entry_value_context: bool = false,
|
||||
};
|
||||
|
||||
pub const ExpressionOptions = struct {
|
||||
pub const Options = struct {
|
||||
/// The address size of the target architecture
|
||||
addr_size: u8 = @sizeOf(usize),
|
||||
|
||||
/// Endianness of the target architecture
|
||||
endian: std.builtin.Endian = builtin.target.cpu.arch.endian(),
|
||||
|
||||
/// Restrict the stack machine to a subset of opcodes used in call frame instructions
|
||||
call_frame_context: bool = false,
|
||||
};
|
||||
|
||||
// Explicitly defined to support executing sub-expressions
|
||||
pub const ExpressionError = error{
|
||||
pub const Error = error{
|
||||
UnimplementedExpressionCall,
|
||||
UnimplementedOpcode,
|
||||
UnimplementedUserOpcode,
|
||||
@@ -75,7 +65,7 @@ pub const ExpressionError = error{
|
||||
/// A stack machine that can decode and run DWARF expressions.
|
||||
/// Expressions can be decoded for non-native address size and endianness,
|
||||
/// but can only be executed if the current target matches the configuration.
|
||||
pub fn StackMachine(comptime options: ExpressionOptions) type {
|
||||
pub fn StackMachine(comptime options: Options) type {
|
||||
const addr_type = switch (options.addr_size) {
|
||||
2 => u16,
|
||||
4 => u32,
|
||||
@@ -186,7 +176,7 @@ pub fn StackMachine(comptime options: ExpressionOptions) type {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn readOperand(stream: *std.io.FixedBufferStream([]const u8), opcode: u8, context: ExpressionContext) !?Operand {
|
||||
pub fn readOperand(stream: *std.io.FixedBufferStream([]const u8), opcode: u8, context: Context) !?Operand {
|
||||
const reader = stream.reader();
|
||||
return switch (opcode) {
|
||||
OP.addr => generic(try reader.readInt(addr_type, options.endian)),
|
||||
@@ -297,9 +287,9 @@ pub fn StackMachine(comptime options: ExpressionOptions) type {
|
||||
self: *Self,
|
||||
expression: []const u8,
|
||||
allocator: std.mem.Allocator,
|
||||
context: ExpressionContext,
|
||||
context: Context,
|
||||
initial_value: ?usize,
|
||||
) ExpressionError!?Value {
|
||||
) Error!?Value {
|
||||
if (initial_value) |i| try self.stack.append(allocator, .{ .generic = i });
|
||||
var stream = std.io.fixedBufferStream(expression);
|
||||
while (try self.step(&stream, allocator, context)) {}
|
||||
@@ -312,8 +302,8 @@ pub fn StackMachine(comptime options: ExpressionOptions) type {
|
||||
self: *Self,
|
||||
stream: *std.io.FixedBufferStream([]const u8),
|
||||
allocator: std.mem.Allocator,
|
||||
context: ExpressionContext,
|
||||
) ExpressionError!bool {
|
||||
context: Context,
|
||||
) Error!bool {
|
||||
if (@sizeOf(usize) != @sizeOf(addr_type) or options.endian != comptime builtin.target.cpu.arch.endian())
|
||||
@compileError("Execution of non-native address sizes / endianness is not supported");
|
||||
|
||||
@@ -792,7 +782,7 @@ pub fn StackMachine(comptime options: ExpressionOptions) type {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn Builder(comptime options: ExpressionOptions) type {
|
||||
pub fn Builder(comptime options: Options) type {
|
||||
const addr_type = switch (options.addr_size) {
|
||||
2 => u16,
|
||||
4 => u32,
|
||||
@@ -1066,7 +1056,7 @@ const testing = std.testing;
|
||||
test "DWARF expressions" {
|
||||
const allocator = std.testing.allocator;
|
||||
|
||||
const options = ExpressionOptions{};
|
||||
const options = Options{};
|
||||
var stack_machine = StackMachine(options){};
|
||||
defer stack_machine.deinit(allocator);
|
||||
|
||||
@@ -1079,7 +1069,7 @@ test "DWARF expressions" {
|
||||
|
||||
// Literals
|
||||
{
|
||||
const context = ExpressionContext{};
|
||||
const context = Context{};
|
||||
for (0..32) |i| {
|
||||
try b.writeLiteral(writer, @intCast(i));
|
||||
}
|
||||
@@ -1125,7 +1115,7 @@ test "DWARF expressions" {
|
||||
try b.writeConst(writer, i28, input[9]);
|
||||
try b.writeAddr(writer, input[10]);
|
||||
|
||||
var mock_compile_unit: dwarf.CompileUnit = undefined;
|
||||
var mock_compile_unit: std.debug.Dwarf.CompileUnit = undefined;
|
||||
mock_compile_unit.addr_base = 1;
|
||||
|
||||
var mock_debug_addr = std.ArrayList(u8).init(allocator);
|
||||
@@ -1135,7 +1125,7 @@ test "DWARF expressions" {
|
||||
try mock_debug_addr.writer().writeInt(usize, input[11], native_endian);
|
||||
try mock_debug_addr.writer().writeInt(usize, input[12], native_endian);
|
||||
|
||||
const context = ExpressionContext{
|
||||
const context = Context{
|
||||
.compile_unit = &mock_compile_unit,
|
||||
.debug_addr = mock_debug_addr.items,
|
||||
};
|
||||
@@ -1185,7 +1175,7 @@ test "DWARF expressions" {
|
||||
};
|
||||
var thread_context: std.debug.ThreadContext = undefined;
|
||||
std.debug.relocateContext(&thread_context);
|
||||
const context = ExpressionContext{
|
||||
const context = Context{
|
||||
.thread_context = &thread_context,
|
||||
.reg_context = reg_context,
|
||||
};
|
||||
@@ -1228,7 +1218,7 @@ test "DWARF expressions" {
|
||||
|
||||
// Stack operations
|
||||
{
|
||||
var context = ExpressionContext{};
|
||||
var context = Context{};
|
||||
|
||||
stack_machine.reset();
|
||||
program.clearRetainingCapacity();
|
||||
@@ -1359,7 +1349,7 @@ test "DWARF expressions" {
|
||||
|
||||
// Arithmetic and Logical Operations
|
||||
{
|
||||
const context = ExpressionContext{};
|
||||
const context = Context{};
|
||||
|
||||
stack_machine.reset();
|
||||
program.clearRetainingCapacity();
|
||||
@@ -1483,7 +1473,7 @@ test "DWARF expressions" {
|
||||
|
||||
// Control Flow Operations
|
||||
{
|
||||
const context = ExpressionContext{};
|
||||
const context = Context{};
|
||||
const expected = .{
|
||||
.{ OP.le, 1, 1, 0 },
|
||||
.{ OP.ge, 1, 0, 1 },
|
||||
@@ -1540,7 +1530,7 @@ test "DWARF expressions" {
|
||||
|
||||
// Type conversions
|
||||
{
|
||||
const context = ExpressionContext{};
|
||||
const context = Context{};
|
||||
stack_machine.reset();
|
||||
program.clearRetainingCapacity();
|
||||
|
||||
@@ -1588,7 +1578,7 @@ test "DWARF expressions" {
|
||||
|
||||
// Special operations
|
||||
{
|
||||
var context = ExpressionContext{};
|
||||
var context = Context{};
|
||||
|
||||
stack_machine.reset();
|
||||
program.clearRetainingCapacity();
|
||||
@@ -1617,7 +1607,7 @@ test "DWARF expressions" {
|
||||
};
|
||||
var thread_context: std.debug.ThreadContext = undefined;
|
||||
std.debug.relocateContext(&thread_context);
|
||||
context = ExpressionContext{
|
||||
context = Context{
|
||||
.thread_context = &thread_context,
|
||||
.reg_context = reg_context,
|
||||
};
|
||||
2702
lib/std/dwarf.zig
2702
lib/std/dwarf.zig
File diff suppressed because it is too large
Load Diff
@@ -327,7 +327,7 @@ pub fn clangAssemblerSupportsMcpuArg(target: std.Target) bool {
|
||||
}
|
||||
|
||||
pub fn needUnwindTables(target: std.Target) bool {
|
||||
return target.os.tag == .windows or target.isDarwin() or std.dwarf.abi.supportsUnwinding(target);
|
||||
return target.os.tag == .windows or target.isDarwin() or std.debug.Dwarf.abi.supportsUnwinding(target);
|
||||
}
|
||||
|
||||
pub fn defaultAddressSpace(
|
||||
|
||||
Reference in New Issue
Block a user