diff --git a/lib/std/dwarf/abi.zig b/lib/std/dwarf/abi.zig index 869993c8e8..fdaac05b87 100644 --- a/lib/std/dwarf/abi.zig +++ b/lib/std/dwarf/abi.zig @@ -25,21 +25,6 @@ pub fn fpRegNum(reg_ctx: RegisterContext) u8 { .x86_64 => 6, .arm => 11, .aarch64 => 29, - - // const ctx = @ptrCast(*const os.ucontext_t, @alignCast(@alignOf(os.ucontext_t), ctx_ptr)); - // const ip = switch (native_os) { - // .macos => @intCast(usize, ctx.mcontext.ss.pc), - // .netbsd => @intCast(usize, ctx.mcontext.gregs[os.REG.PC]), - // .freebsd => @intCast(usize, ctx.mcontext.gpregs.elr), - // else => @intCast(usize, ctx.mcontext.pc), - // }; - // // x29 is the ABI-designated frame pointer - // const bp = switch (native_os) { - // .macos => @intCast(usize, ctx.mcontext.ss.fp), - // .netbsd => @intCast(usize, ctx.mcontext.gregs[os.REG.FP]), - // .freebsd => @intCast(usize, ctx.mcontext.gpregs.x[os.REG.FP]), - // else => @intCast(usize, ctx.mcontext.regs[29]), - // }; else => unreachable, }; } @@ -231,7 +216,10 @@ pub fn regBytes(ucontext_ptr: anytype, reg_number: u8, reg_ctx: ?RegisterContext 0...29 => mem.asBytes(&ucontext_ptr.mcontext.gpregs.x[reg_number]), 30 => mem.asBytes(&ucontext_ptr.mcontext.gpregs.lr), 31 => mem.asBytes(&ucontext_ptr.mcontext.gpregs.sp), - 32 => mem.asBytes(&ucontext_ptr.mcontext.gpregs.elr), // TODO: This seems wrong, but it was in the old debug.zig code for PC, check this + + // TODO: This seems wrong, but it was in the previous debug.zig code for mapping PC, check this + 32 => mem.asBytes(&ucontext_ptr.mcontext.gpregs.elr), + else => error.InvalidRegister, }, else => switch (reg_number) { @@ -252,76 +240,3 @@ pub fn getRegDefaultValue(reg_number: u8, out: []u8) void { _ = reg_number; @memset(out, undefined); } - -fn writeUnknownReg(writer: anytype, reg_number: u8) !void { - try writer.print("reg{}", .{reg_number}); -} - -pub fn writeRegisterName(writer: anytype, arch: ?std.Target.Cpu.Arch, reg_number: u8) !void { - if (arch) |a| { - switch (a) { - .x86_64 => { - switch (reg_number) { - 0 => try writer.writeAll("RAX"), - 1 => try writer.writeAll("RDX"), - 2 => try writer.writeAll("RCX"), - 3 => try writer.writeAll("RBX"), - 4 => try writer.writeAll("RSI"), - 5 => try writer.writeAll("RDI"), - 6 => try writer.writeAll("RBP"), - 7 => try writer.writeAll("RSP"), - 8...15 => try writer.print("R{}", .{reg_number}), - 16 => try writer.writeAll("RIP"), - 17...32 => try writer.print("XMM{}", .{reg_number - 17}), - 33...40 => try writer.print("ST{}", .{reg_number - 33}), - 41...48 => try writer.print("MM{}", .{reg_number - 41}), - 49 => try writer.writeAll("RFLAGS"), - 50 => try writer.writeAll("ES"), - 51 => try writer.writeAll("CS"), - 52 => try writer.writeAll("SS"), - 53 => try writer.writeAll("DS"), - 54 => try writer.writeAll("FS"), - 55 => try writer.writeAll("GS"), - // 56-57 Reserved - 58 => try writer.writeAll("FS.BASE"), - 59 => try writer.writeAll("GS.BASE"), - // 60-61 Reserved - 62 => try writer.writeAll("TR"), - 63 => try writer.writeAll("LDTR"), - 64 => try writer.writeAll("MXCSR"), - 65 => try writer.writeAll("FCW"), - 66 => try writer.writeAll("FSW"), - 67...82 => try writer.print("XMM{}", .{reg_number - 51}), - // 83-117 Reserved - 118...125 => try writer.print("K{}", .{reg_number - 118}), - // 126-129 Reserved - else => try writeUnknownReg(writer, reg_number), - } - }, - - // TODO: Add x86, aarch64 - - else => try writeUnknownReg(writer, reg_number), - } - } else try writeUnknownReg(writer, reg_number); -} - -const FormatRegisterData = struct { - reg_number: u8, - arch: ?std.Target.Cpu.Arch, -}; - -pub fn formatRegister( - data: FormatRegisterData, - comptime fmt: []const u8, - options: std.fmt.FormatOptions, - writer: anytype, -) !void { - _ = fmt; - _ = options; - try writeRegisterName(writer, data.arch, data.reg_number); -} - -pub fn fmtRegister(reg_number: u8, arch: ?std.Target.Cpu.Arch) std.fmt.Formatter(formatRegister) { - return .{ .data = .{ .reg_number = reg_number, .arch = arch } }; -} diff --git a/lib/std/dwarf/call_frame.zig b/lib/std/dwarf/call_frame.zig index 8a8d083031..853297a2f2 100644 --- a/lib/std/dwarf/call_frame.zig +++ b/lib/std/dwarf/call_frame.zig @@ -38,12 +38,12 @@ const Opcode = enum(u8) { val_expression = 0x16, // These opcodes encode an operand in the lower 6 bits of the opcode itself - pub const lo_inline = Opcode.advance_loc; + pub const lo_inline = @enumToInt(Opcode.advance_loc); pub const hi_inline = @enumToInt(Opcode.restore) | 0b111111; // These opcodes are trailed by zero or more operands - pub const lo_reserved = Opcode.nop; - pub const hi_reserved = Opcode.val_expression; + pub const lo_reserved = @enumToInt(Opcode.nop); + pub const hi_reserved = @enumToInt(Opcode.val_expression); // Vendor-specific opcodes pub const lo_user = 0x1c; @@ -187,28 +187,40 @@ pub const Instruction = union(Opcode) { val_offset_sf: InstructionType(.{ .a = .uleb128_offset, .b = .sleb128_offset }), val_expression: InstructionType(.{ .a = .uleb128_offset, .block = .block }), + fn readOperands( + self: *Instruction, + stream: *std.io.FixedBufferStream([]const u8), + opcode_value: ?u6, + addr_size_bytes: u8, + endian: std.builtin.Endian, + ) !void { + switch (self.*) { + inline else => |*inst| inst.* = try @TypeOf(inst.*).read(stream, opcode_value, addr_size_bytes, endian), + } + } + pub fn read( stream: *std.io.FixedBufferStream([]const u8), addr_size_bytes: u8, endian: std.builtin.Endian, ) !Instruction { - @setEvalBranchQuota(1800); - return switch (try stream.reader().readByte()) { - inline @enumToInt(Opcode.lo_inline)...Opcode.hi_inline => |opcode| blk: { + inline Opcode.lo_inline...Opcode.hi_inline => |opcode| blk: { const e = @intToEnum(Opcode, opcode & 0b11000000); - const payload_type = std.meta.TagPayload(Instruction, e); - const value = try payload_type.read(stream, @intCast(u6, opcode & 0b111111), addr_size_bytes, endian); - break :blk @unionInit(Instruction, @tagName(e), value); + var result = @unionInit(Instruction, @tagName(e), undefined); + try result.readOperands(stream, @intCast(u6, opcode & 0b111111), addr_size_bytes, endian); + break :blk result; }, - inline @enumToInt(Opcode.lo_reserved)...@enumToInt(Opcode.hi_reserved) => |opcode| blk: { + inline Opcode.lo_reserved...Opcode.hi_reserved => |opcode| blk: { const e = @intToEnum(Opcode, opcode); - const payload_type = std.meta.TagPayload(Instruction, e); - const value = try payload_type.read(stream, null, addr_size_bytes, endian); - break :blk @unionInit(Instruction, @tagName(e), value); + var result = @unionInit(Instruction, @tagName(e), undefined); + try result.readOperands(stream, null, addr_size_bytes, endian); + break :blk result; }, Opcode.lo_user...Opcode.hi_user => error.UnimplementedUserOpcode, else => |opcode| blk: { + + // TODO: Remove this std.debug.print("Opcode {x}\n", .{opcode}); break :blk error.InvalidOpcode;