mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
dwarf: add abi.stripInstructionPtrAuthCode
This commit is contained in:
parent
ec96095efd
commit
ba813d00f5
@ -1758,12 +1758,16 @@ pub const DwarfInfo = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (has_next_ip) {
|
if (has_next_ip) {
|
||||||
context.pc = mem.readIntSliceNative(usize, try abi.regBytes(context.thread_context, cie.return_address_register, context.reg_context));
|
context.pc = abi.stripInstructionPtrAuthCode(mem.readIntSliceNative(usize, try abi.regBytes(
|
||||||
|
context.thread_context,
|
||||||
|
cie.return_address_register,
|
||||||
|
context.reg_context,
|
||||||
|
)));
|
||||||
} else {
|
} else {
|
||||||
context.pc = 0;
|
context.pc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
mem.writeIntSliceNative(usize, try abi.regBytes(context.thread_context, abi.spRegNum(context.reg_context), context.reg_context), context.cfa.?);
|
(try abi.regValueNative(usize, context.thread_context, abi.spRegNum(context.reg_context), context.reg_context)).* = context.cfa.?;
|
||||||
|
|
||||||
// The call instruction will have pushed the address of the instruction that follows the call as the return address
|
// The call instruction will have pushed the address of the instruction that follows the call as the return address
|
||||||
// However, this return address may be past the end of the function if the caller was `noreturn`. By subtracting one,
|
// However, this return address may be past the end of the function if the caller was `noreturn`. By subtracting one,
|
||||||
@ -1786,7 +1790,7 @@ pub const UnwindContext = struct {
|
|||||||
stack_machine: expressions.StackMachine(.{ .call_frame_context = true }) = .{},
|
stack_machine: expressions.StackMachine(.{ .call_frame_context = true }) = .{},
|
||||||
|
|
||||||
pub fn init(allocator: mem.Allocator, thread_context: *const debug.ThreadContext, isValidMemory: *const fn (address: usize) bool) !UnwindContext {
|
pub fn init(allocator: mem.Allocator, thread_context: *const debug.ThreadContext, isValidMemory: *const fn (address: usize) bool) !UnwindContext {
|
||||||
const pc = mem.readIntSliceNative(usize, try abi.regBytes(thread_context, abi.ipRegNum(), null));
|
const pc = abi.stripInstructionPtrAuthCode((try abi.regValueNative(usize, thread_context, abi.ipRegNum(), null)).*);
|
||||||
|
|
||||||
const context_copy = try allocator.create(debug.ThreadContext);
|
const context_copy = try allocator.create(debug.ThreadContext);
|
||||||
debug.copyContext(thread_context, context_copy);
|
debug.copyContext(thread_context, context_copy);
|
||||||
|
|||||||
@ -45,6 +45,27 @@ pub fn spRegNum(reg_context: RegisterContext) u8 {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Some platforms use pointer authentication - the upper bits of instruction pointers contain a signature.
|
||||||
|
/// This function clears these signature bits to make the pointer usable.
|
||||||
|
pub inline fn stripInstructionPtrAuthCode(ptr: usize) usize {
|
||||||
|
if (builtin.cpu.arch == .aarch64) {
|
||||||
|
// `hint 0x07` maps to `xpaclri` (or `nop` if the hardware doesn't support it)
|
||||||
|
// The save / restore is because `xpaclri` operates on x30 (LR)
|
||||||
|
return asm (
|
||||||
|
\\mov x16, x30
|
||||||
|
\\mov x30, x15
|
||||||
|
\\hint 0x07
|
||||||
|
\\mov x15, x30
|
||||||
|
\\mov x30, x16
|
||||||
|
: [ret] "={x15}" (-> usize),
|
||||||
|
: [ptr] "{x15}" (ptr),
|
||||||
|
: "x16"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
pub const RegisterContext = struct {
|
pub const RegisterContext = struct {
|
||||||
eh_frame: bool,
|
eh_frame: bool,
|
||||||
is_macho: bool,
|
is_macho: bool,
|
||||||
@ -160,7 +181,6 @@ pub fn regBytes(
|
|||||||
if (!std.debug.have_ucontext) return error.ThreadContextNotSupported;
|
if (!std.debug.have_ucontext) return error.ThreadContextNotSupported;
|
||||||
|
|
||||||
const ucontext_ptr = thread_context_ptr;
|
const ucontext_ptr = thread_context_ptr;
|
||||||
var m = &ucontext_ptr.mcontext;
|
|
||||||
return switch (builtin.cpu.arch) {
|
return switch (builtin.cpu.arch) {
|
||||||
.x86 => switch (builtin.os.tag) {
|
.x86 => switch (builtin.os.tag) {
|
||||||
.linux, .netbsd, .solaris => switch (reg_number) {
|
.linux, .netbsd, .solaris => switch (reg_number) {
|
||||||
@ -216,7 +236,7 @@ pub fn regBytes(
|
|||||||
14 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.R14]),
|
14 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.R14]),
|
||||||
15 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.R15]),
|
15 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.R15]),
|
||||||
16 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.RIP]),
|
16 => mem.asBytes(&ucontext_ptr.mcontext.gregs[os.REG.RIP]),
|
||||||
17...32 => |i| mem.asBytes(&m.fpregs.xmm[i - 17]),
|
17...32 => |i| mem.asBytes(&ucontext_ptr.mcontext.fpregs.xmm[i - 17]),
|
||||||
else => error.InvalidRegister,
|
else => error.InvalidRegister,
|
||||||
},
|
},
|
||||||
.freebsd => switch (reg_number) {
|
.freebsd => switch (reg_number) {
|
||||||
@ -313,6 +333,10 @@ pub fn regBytes(
|
|||||||
30 => mem.asBytes(&ucontext_ptr.mcontext.ss.lr),
|
30 => mem.asBytes(&ucontext_ptr.mcontext.ss.lr),
|
||||||
31 => mem.asBytes(&ucontext_ptr.mcontext.ss.sp),
|
31 => mem.asBytes(&ucontext_ptr.mcontext.ss.sp),
|
||||||
32 => mem.asBytes(&ucontext_ptr.mcontext.ss.pc),
|
32 => mem.asBytes(&ucontext_ptr.mcontext.ss.pc),
|
||||||
|
|
||||||
|
// TODO: Find storage for this state
|
||||||
|
//34 => mem.asBytes(&ucontext_ptr.ra_sign_state),
|
||||||
|
|
||||||
// V0-V31
|
// V0-V31
|
||||||
64...95 => mem.asBytes(&ucontext_ptr.mcontext.ns.q[reg_number - 64]),
|
64...95 => mem.asBytes(&ucontext_ptr.mcontext.ns.q[reg_number - 64]),
|
||||||
else => error.InvalidRegister,
|
else => error.InvalidRegister,
|
||||||
|
|||||||
@ -2459,7 +2459,7 @@ pub fn unwindFrame(context: *dwarf.UnwindContext, unwind_info: []const u8, modul
|
|||||||
else => return error.UnimplementedArch,
|
else => return error.UnimplementedArch,
|
||||||
};
|
};
|
||||||
|
|
||||||
context.pc = new_ip;
|
context.pc = dwarf.abi.stripInstructionPtrAuthCode(new_ip);
|
||||||
if (context.pc > 0) context.pc -= 1;
|
if (context.pc > 0) context.pc -= 1;
|
||||||
return new_ip;
|
return new_ip;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user