From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15387 invoked by alias); 12 Jun 2008 05:44:26 -0000 Received: (qmail 15366 invoked by uid 22791); 12 Jun 2008 05:44:23 -0000 X-Spam-Status: No, hits=-0.8 required=5.0 tests=AWL,BAYES_50,J_CHICKENPOX_74,SPF_PASS X-Spam-Check-By: sourceware.org Received: from igw1.br.ibm.com (HELO igw1.br.ibm.com) (32.104.18.24) by sourceware.org (qpsmtpd/0.31) with ESMTP; Thu, 12 Jun 2008 05:43:57 +0000 Received: from mailhub3.br.ibm.com (mailhub3 [9.18.232.110]) by igw1.br.ibm.com (Postfix) with ESMTP id E279E32C16C for ; Thu, 12 Jun 2008 02:18:20 -0300 (BRST) Received: from d24av02.br.ibm.com (d24av02.br.ibm.com [9.18.232.47]) by mailhub3.br.ibm.com (8.13.8/8.13.8/NCO v8.7) with ESMTP id m5C5hv3k1732704 for ; Thu, 12 Jun 2008 02:43:57 -0300 Received: from d24av02.br.ibm.com (loopback [127.0.0.1]) by d24av02.br.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id m5C5hqRp015847 for ; Thu, 12 Jun 2008 02:43:52 -0300 Received: from [9.8.6.159] ([9.8.6.159]) by d24av02.br.ibm.com (8.12.11.20060308/8.12.11) with ESMTP id m5C5hqWj015842 for ; Thu, 12 Jun 2008 02:43:52 -0300 Subject: [RFC] powerpc watchpoints support From: Thiago Jung Bauermann To: frysk ml Content-Type: text/plain Date: Fri, 13 Jun 2008 04:07:00 -0000 Message-Id: <1213249424.11485.62.camel@localhost.localdomain> Mime-Version: 1.0 X-Mailer: Evolution 2.22.2 Content-Transfer-Encoding: 7bit X-IsSubscribed: yes Mailing-List: contact frysk-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: frysk-owner@sourceware.org X-SW-Source: 2008-q2/txt/msg00100.txt.bz2 Hi, There are problems I need to fix before this patch is really usable, but I wanted to post it anyway to get input on the direction this is going. I believe I'm following what Cagney had in mind, when he suggested to use RegisterSet to get the siginfo structure from the inferior task. Noteworthy features: - Java-only siginfo_t unpacker, found in frysk.isa.signals.SigInfo. - new getSigInfo method in LinuxPtraceTask, since PTRACE_[GS]ETSIGINFO is available in all architectures supported by Linux, AFAICT. - PPCWatchpointFunctions.hasWatchpointTriggered casts the received Task to a LinuxPtraceTask, to use its getSigInfo method and with it determine if the watchpoint triggered. The rest of PPCWatchpointFunctions didn't change relative to the last RFC I posted. - Batteries not included. Some assembly required. -- []'s Thiago Jung Bauermann Software Engineer IBM Linux Technology Center diff --git a/frysk-core/frysk/isa/banks/LinuxPPCRegisterBanks.java b/frysk-core/frysk/isa/banks/LinuxPPCRegisterBanks.java index b2fd02b..e08a5ce 100644 --- a/frysk-core/frysk/isa/banks/LinuxPPCRegisterBanks.java +++ b/frysk-core/frysk/isa/banks/LinuxPPCRegisterBanks.java @@ -260,4 +260,6 @@ public class LinuxPPCRegisterBanks { .add(new BankRegister(148*8, 8, PPC64Registers.VRSAVE)) // PT_VRSAVE (PT_VR0 + 33*2), index 148 ; + public static final BankRegisterMap DEBUGREGS + = new BankRegisterMap().add(new BankRegister(0, 8, PPC64Registers.DABR)); } diff --git a/frysk-core/frysk/isa/banks/PPCBankRegisters.java b/frysk-core/frysk/isa/banks/PPCBankRegisters.java index 40d72d6..b8588b9 100644 --- a/frysk-core/frysk/isa/banks/PPCBankRegisters.java +++ b/frysk-core/frysk/isa/banks/PPCBankRegisters.java @@ -55,6 +55,7 @@ public class PPCBankRegisters { = new BankArrayRegisterMap() .add(0, LinuxPPCRegisterBanks.GREGS32) .add(0, LinuxPPCRegisterBanks.FPREGS32) + .add(1, LinuxPPCRegisterBanks.DEBUGREGS) ; /** @@ -66,6 +67,7 @@ public class PPCBankRegisters { .add(0, LinuxPPCRegisterBanks.FPREGS64) // AltiVec registers go to a separate note section called NT_PPC_VMX .add(0, LinuxPPCRegisterBanks.VRREGS64) + .add(1, LinuxPPCRegisterBanks.DEBUGREGS) ; public static final BankArrayRegisterMap PPC32BE_ON_PPC64BE diff --git a/frysk-core/frysk/isa/registers/PPC32Registers.java b/frysk-core/frysk/isa/registers/PPC32Registers.java index 1aabb9c..adb990c 100644 --- a/frysk-core/frysk/isa/registers/PPC32Registers.java +++ b/frysk-core/frysk/isa/registers/PPC32Registers.java @@ -246,6 +246,12 @@ public class PPC32Registers extends Registers { = new Register("fpscr", StandardTypes.INT32B_T); /* + * Debug register. + */ + public static final Register DABR + = new Register("dabr", StandardTypes.INT64B_T); + + /* * Defining Register Groups */ public static final RegisterGroup GENERAL diff --git a/frysk-core/frysk/isa/registers/PPC64Registers.java b/frysk-core/frysk/isa/registers/PPC64Registers.java index a5505c4..248c769 100644 --- a/frysk-core/frysk/isa/registers/PPC64Registers.java +++ b/frysk-core/frysk/isa/registers/PPC64Registers.java @@ -345,6 +345,12 @@ public class PPC64Registers extends Registers { public static final Register SPEFSCR = new Register("spefscr", StandardTypes.INT64B_T); + /* + * Debug register. + */ + public static final Register DABR + = new Register("dabr", StandardTypes.INT64B_T); + /* * Defining Register Groups */ diff --git a/frysk-core/frysk/isa/signals/SigInfo.java b/frysk-core/frysk/isa/signals/SigInfo.java new file mode 100644 index 0000000..1372b96 --- /dev/null +++ b/frysk-core/frysk/isa/signals/SigInfo.java @@ -0,0 +1,260 @@ +// This file is part of the program FRYSK. +// +// Copyright 2008, IBM Corp. +// +// FRYSK is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// FRYSK is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FRYSK; if not, write to the Free Software Foundation, +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// In addition, as a special exception, Red Hat, Inc. gives You the +// additional right to link the code of FRYSK with code not covered +// under the GNU General Public License ("Non-GPL Code") and to +// distribute linked combinations including the two, subject to the +// limitations in this paragraph. Non-GPL Code permitted under this +// exception must only link to the code of FRYSK through those well +// defined interfaces identified in the file named EXCEPTION found in +// the source code files (the "Approved Interfaces"). The files of +// Non-GPL Code may instantiate templates or use macros or inline +// functions from the Approved Interfaces without causing the +// resulting work to be covered by the GNU General Public +// License. Only Red Hat, Inc. may make changes or additions to the +// list of Approved Interfaces. You must obey the GNU General Public +// License in all respects for all of the FRYSK code and other code +// used in conjunction with FRYSK except the Non-GPL Code covered by +// this exception. If you modify this file, you may extend this +// exception to your version of the file, but you are not obligated to +// do so. If you do not wish to provide this exception without +// modification, you must delete this exception statement from your +// version and license this file solely under the GPL without +// exception. + +package frysk.isa.signals; + +import inua.eio.ArrayByteBuffer; +import frysk.isa.ISA; + +public class SigInfo { + + static final int SI_SIGNO = 0; + + static final int SI_ERRNO = 1; + + static final int SI_CODE = 2; + + static final int SI_PID = 3; + + static final int SI_UID = 4; + + static final int SI_TIMERID = 5; + + static final int SI_OVERRUN = 6; + + static final int SI_STATUS = 7; + + static final int SI_UTIME = 8; + + static final int SI_STIME = 9; + + static final int SI_VALUE = 10; + + static final int SI_INT = 11; + + static final int SI_PTR = 12; + + static final int SI_ADDR = 13; + + static final int SI_BAND = 14; + + static final int SI_FD = 15; + + static final int[] ppc32Offets = { 0, // si_signo + 4, // si_errno + 8, // si_code + 12, // si_pid + 16, // si_uid + 12, // si_timerid + 16, // si_overrun + 20, // si_status + 24, // si_utime + 28, // si_stime + 20, // si_value + 20, // si_int + 20, // si_ptr + 12, // si_addr + 12, // si_band + 16 // si_fd + }; + + static final int[] ppc64Offets = { 0, // si_signo + 4, // si_errno + 8, // si_code + 16, // si_pid + 20, // si_uid + 16, // si_timerid + 20, // si_overrun + 24, // si_status + 32, // si_utime + 40, // si_stime + 24, // si_value + 24, // si_int + 24, // si_ptr + 16, // si_addr + 16, // si_band + 24 // si_fd + }; + + static final int[] ia32Offets = { 0, // si_signo + 4, // si_errno + 8, // si_code + 12, // si_pid + 16, // si_uid + 12, // si_timerid + 16, // si_overrun + 20, // si_status + 24, // si_utime + 28, // si_stime + 20, // si_value + 20, // si_int + 20, // si_ptr + 12, // si_addr + 12, // si_band + 16 // si_fd + }; + + static final int[] x8664Offets = { 0, // si_signo + 4, // si_errno + 8, // si_code + 16, // si_pid + 20, // si_uid + 16, // si_timerid + 20, // si_overrun + 24, // si_status + 32, // si_utime + 40, // si_stime + 24, // si_value + 24, // si_int + 24, // si_ptr + 16, // si_addr + 16, // si_band + 24 // si_fd + }; + + private ArrayByteBuffer siginfo; + + private int[] offsets; + + private ISA isa; + + public SigInfo(byte[] aSiginfo, ISA anIsa) { + siginfo = new ArrayByteBuffer(aSiginfo); + siginfo.order(anIsa.order()); + + if (anIsa == ISA.PPC32BE) + offsets = ppc32Offets; + else if (anIsa == ISA.PPC64BE) + offsets = ppc64Offets; + else if (anIsa == ISA.IA32) + offsets = ia32Offets; + else if (anIsa == ISA.X8664) + offsets = x8664Offets; + else + throw new RuntimeException("Unhandled isa: " + anIsa); + } + + public int getSigno() { + return siginfo.getInt(offsets[SI_SIGNO]); + } + + public int getErrno() { + return siginfo.getInt(offsets[SI_ERRNO]); + } + + public int getCode() { + return siginfo.getInt(offsets[SI_CODE]); + } + + public int getPid() { + return siginfo.getInt(offsets[SI_PID]); + } + + public long getUid() { + return siginfo.getUInt(offsets[SI_UID]); + } + + public int getTimerid() { + return siginfo.getInt(offsets[SI_TIMERID]); + } + + public int getOverrun() { + return siginfo.getInt(offsets[SI_OVERRUN]); + } + + public int getStatus() { + return siginfo.getInt(offsets[SI_STATUS]); + } + + public long getUtime() { + if (isa == ISA.PPC32BE || isa == ISA.IA32) + return siginfo.getInt(offsets[SI_UTIME]); + else if (isa == ISA.PPC64BE || isa == ISA.X8664) + return siginfo.getLong(offsets[SI_UTIME]); + + throw new RuntimeException("Unhandled isa: " + isa); + } + + public long getStime() { + if (isa == ISA.PPC32BE || isa == ISA.IA32) + return siginfo.getInt(offsets[SI_STIME]); + else if (isa == ISA.PPC64BE || isa == ISA.X8664) + return siginfo.getLong(offsets[SI_STIME]); + + throw new RuntimeException("Unhandled isa: " + isa); + } + + // No getValue since it would have to return a union sigval_t. + // getInt and getptr already provide access to the union members. + + public int getInt() { + return siginfo.getInt(offsets[SI_INT]); + } + + public long getPtr() { + if (isa == ISA.PPC32BE || isa == ISA.IA32) + return siginfo.getUInt(offsets[SI_PTR]); + else if (isa == ISA.PPC64BE || isa == ISA.X8664) + return siginfo.getULong(offsets[SI_PTR]); + + throw new RuntimeException("Unhandled isa: " + isa); + } + + public long getAddr() { + if (isa == ISA.PPC32BE || isa == ISA.IA32) + return siginfo.getUInt(offsets[SI_ADDR]); + else if (isa == ISA.PPC64BE || isa == ISA.X8664) + return siginfo.getULong(offsets[SI_ADDR]); + + throw new RuntimeException("Unhandled isa: " + isa); + } + + public long getBand() { + if (isa == ISA.PPC32BE || isa == ISA.IA32) + return siginfo.getInt(offsets[SI_BAND]); + else if (isa == ISA.PPC64BE || isa == ISA.X8664) + return siginfo.getLong(offsets[SI_BAND]); + + throw new RuntimeException("Unhandled isa: " + isa); + } + + public int getFd() { + return siginfo.getInt(offsets[SI_FD]); + } +} diff --git a/frysk-core/frysk/isa/watchpoints/PPCWatchpointFunctions.java b/frysk-core/frysk/isa/watchpoints/PPCWatchpointFunctions.java new file mode 100644 index 0000000..4157025 --- /dev/null +++ b/frysk-core/frysk/isa/watchpoints/PPCWatchpointFunctions.java @@ -0,0 +1,204 @@ +// This file is part of the program FRYSK. +// +// Copyright 2008, Red Hat Inc. +// +// FRYSK is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// FRYSK is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with FRYSK; if not, write to the Free Software Foundation, +// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// In addition, as a special exception, Red Hat, Inc. gives You the +// additional right to link the code of FRYSK with code not covered +// under the GNU General Public License ("Non-GPL Code") and to +// distribute linked combinations including the two, subject to the +// limitations in this paragraph. Non-GPL Code permitted under this +// exception must only link to the code of FRYSK through those well +// defined interfaces identified in the file named EXCEPTION found in +// the source code files (the "Approved Interfaces"). The files of +// Non-GPL Code may instantiate templates or use macros or inline +// functions from the Approved Interfaces without causing the +// resulting work to be covered by the GNU General Public +// License. Only Red Hat, Inc. may make changes or additions to the +// list of Approved Interfaces. You must obey the GNU General Public +// License in all respects for all of the FRYSK code and other code +// used in conjunction with FRYSK except the Non-GPL Code covered by +// this exception. If you modify this file, you may extend this +// exception to your version of the file, but you are not obligated to +// do so. If you do not wish to provide this exception without +// modification, you must delete this exception statement from your +// version and license this file solely under the GPL without +// exception. + +package frysk.isa.watchpoints; + +import frysk.isa.registers.PPC64Registers; +import frysk.isa.signals.SigInfo; +import frysk.isa.signals.StandardSignal; +import frysk.proc.Task; +import frysk.proc.live.LinuxPtraceTask; + +class PPCWatchpointFunctions extends WatchpointFunctions { + + /** + * @see /usr/src/linux/include/asm-powerpc/siginfo.h. + */ + private static final int TRAP_HWBKPT = 4; + + public PPCWatchpointFunctions() { + // Architecture Watchpoint Count. Number of usable + // Address-Breakpoint Registers: only one, DABR. + noOfWatchpoints = 1; + } + + /** + * Builds and sets a hardware watchpoint on a task. + * + * @param task - + * task to set a watchpoint on. + * @param index - + * watchpoint number to write. 4 on x8664 + * @param addr - + * linear virtual address to watch. + * @param range - + * length of range to watch. Normally 1,24, or 8 bytes. + * @param writeOnly - + * When true, only trigger when address is written. + * False, trigger when address is read or written to. + */ + public void setWatchpoint(Task task, int index, long addr, int range, + boolean writeOnly) { + + if (index != 0) { + throw new RuntimeException("Invalid hardware watchpoint index." + + "Has to be 0."); + } + + if (range != 8) { + throw new RuntimeException("Invalid size for watchpoint " + + "range. Has to be 8."); + } + + if ((addr & ~7) != addr) + throw new RuntimeException( + "Address 0x" + + Long.toHexString(addr) + + " is not aligned on an 8 byte boundary. Cannot set watchpoint."); + + if (writeOnly) + // set translation and write bits + addr |= 6; + else + // set translation and read bits + addr |= 5; + + task.setRegister(PPC64Registers.DABR, addr); + } + + /** + * Reads a watchpoint. Takes a task, and an index. + * + * @param task - + * task to read a watchpoint from. + * @param index - + * watchpoint number to read. + * + * @return Watchpoint - value of Watchpoint at register. + */ + public Watchpoint readWatchpoint(Task task, int index) { + + if (index != 0) { + throw new RuntimeException("Invalid hardware watchpoint index." + + "Has to be 0."); + } + + // Get Address from watchpoint register + long dabr_value = task.getRegister(PPC64Registers.DABR); + long address = dabr_value & ~7; + boolean writeOnly = testBit(address, 0) && !testBit(address, 1); + + return Watchpoint.create(address, 8, index, writeOnly); + } + + /** + * Deletes a watchpoint. Takes a task, and an index. + * + * @param task - + * task on which to delete a watchpoint. + * @param index - + * watchpoint number to delete. + * + * @return long - value of register for wp + */ + public final void deleteWatchpoint(Task task, int index) { + task.setRegister(PPC64Registers.DABR, 0); + } + + /** + * Reads the Debug control register. + * + * @param task - + * task to read the debug control register from. + */ + protected long readControlRegister(Task task) { + throw new RuntimeException( + "There is no debug control register in PowerPC."); + } + + /** + * Reads the Debug cstatus register. + * + * @param task - + * task to read the debug status register from. + */ + protected long readStatusRegister(Task task) { + throw new RuntimeException( + "There is no debug status register in PowerPC."); + } + + /** + * Reads the Debug Status Register and checks if the breakpoint + * specified has fired. + * + * @param task - + * task to read the debug control register from. + * + * @param index - + * Debug register to check + */ + public boolean hasWatchpointTriggered(Task task, int index) { + SigInfo siginfo = ((LinuxPtraceTask) task).getSigInfo(); + + if ((siginfo.getSigno() != task.getSignalTable().get( + StandardSignal.TRAP).intValue()) + || ((siginfo.getCode() & 0xFFFF) != TRAP_HWBKPT)) + return false; + + return true; + } + + /** + * Resets the appropriate bit in the debug status register after a + * watchpoint has triggered, thereby reseting it. + * + * @param task - + * task to read the debug control register from. + * @param index - + * Debug register to reset. + */ + public void resetWatchpoint(Task task, int index) { + // There is no need to reset a watchpoint after it triggers. + } + + private boolean testBit(long register, int bitToTest) { + return (register & (1L << bitToTest)) != 0; + } + +} diff --git a/frysk-core/frysk/isa/watchpoints/WatchpointFunctionFactory.java b/frysk-core/frysk/isa/watchpoints/WatchpointFunctionFactory.java index fe8b81b..5ff68da 100644 --- a/frysk-core/frysk/isa/watchpoints/WatchpointFunctionFactory.java +++ b/frysk-core/frysk/isa/watchpoints/WatchpointFunctionFactory.java @@ -50,6 +50,8 @@ public class WatchpointFunctionFactory { private static final ISAMap watchpointTables = new ISAMap("watchpoint table") .put(ISA.IA32, new IA32WatchpointFunctions()) .put(ISA.X8664, new X8664WatchpointFunctions()) + .put(ISA.PPC32BE, new PPCWatchpointFunctions()) + .put(ISA.PPC64BE, new PPCWatchpointFunctions()) ; public static WatchpointFunctions getWatchpointFunctions(ISA isa) { diff --git a/frysk-core/frysk/proc/live/LinuxPtraceTask.java b/frysk-core/frysk/proc/live/LinuxPtraceTask.java index 0ecadb3..8ef8f5a 100644 --- a/frysk-core/frysk/proc/live/LinuxPtraceTask.java +++ b/frysk-core/frysk/proc/live/LinuxPtraceTask.java @@ -61,7 +61,9 @@ import frysk.sys.Errno; import frysk.sys.ProcessIdentifier; import frysk.sys.ptrace.Ptrace; import frysk.sys.ptrace.AddressSpace; +import frysk.sys.ptrace.RegisterSet; import frysk.sys.Signal; +import frysk.isa.signals.SigInfo; import frysk.isa.syscalls.Syscall; import frysk.isa.ISA; import frysk.isa.ElfMap; @@ -1132,6 +1134,13 @@ public class LinuxPtraceTask extends LiveTask { setRegister(pcRegister(), addr); } + public SigInfo getSigInfo() { + byte[] buffer = new byte[RegisterSet.SIGINFO.length()]; + + RegisterSet.SIGINFO.transfer(tid, buffer, false); + return new SigInfo(buffer, getISA()); + } + protected void clearIsa() { fine.log(this, "clearIsa"); super.clearIsa(); diff --git a/frysk-core/frysk/proc/live/PtraceRegisterBanksFactory.java b/frysk-core/frysk/proc/live/PtraceRegisterBanksFactory.java index daa86d9..656f687 100644 --- a/frysk-core/frysk/proc/live/PtraceRegisterBanksFactory.java +++ b/frysk-core/frysk/proc/live/PtraceRegisterBanksFactory.java @@ -85,7 +85,8 @@ class PtraceRegisterBanksFactory { private static ByteBuffer[] ppcBanksBE(ProcessIdentifier pid) { ByteBuffer[] bankBuffers = new ByteBuffer[] { - new AddressSpaceByteBuffer(pid, AddressSpace.USR) + new AddressSpaceByteBuffer(pid, AddressSpace.USR), + new RegisterSetByteBuffer(pid, RegisterSet.DEBUGREGS) }; for (int i = 0; i < bankBuffers.length; i++) { diff --git a/frysk-sys/frysk/sys/ptrace/RegisterSet.java b/frysk-sys/frysk/sys/ptrace/RegisterSet.java index 7fa028a..b1651fb 100644 --- a/frysk-sys/frysk/sys/ptrace/RegisterSet.java +++ b/frysk-sys/frysk/sys/ptrace/RegisterSet.java @@ -80,8 +80,12 @@ public class RegisterSet { private static native RegisterSet regs(); private static native RegisterSet fpregs(); private static native RegisterSet fpxregs(); + private static native RegisterSet debugregs(); + private static native RegisterSet siginfo(); public static final RegisterSet REGS = regs(); public static final RegisterSet FPREGS = fpregs(); public static final RegisterSet FPXREGS = fpxregs(); + public static final RegisterSet DEBUGREGS = debugregs(); + public static final RegisterSet SIGINFO = siginfo(); } diff --git a/frysk-sys/frysk/sys/ptrace/cni/RegisterSet.cxx b/frysk-sys/frysk/sys/ptrace/cni/RegisterSet.cxx index 2c3a861..bd04435 100644 --- a/frysk-sys/frysk/sys/ptrace/cni/RegisterSet.cxx +++ b/frysk-sys/frysk/sys/ptrace/cni/RegisterSet.cxx @@ -38,6 +38,7 @@ // exception. #include +#include // for siginfo_t #include #include #include "linux.ptrace.h" @@ -87,3 +88,22 @@ frysk::sys::ptrace::RegisterSet::fpxregs() { return NULL; #endif } + +frysk::sys::ptrace::RegisterSet* +frysk::sys::ptrace::RegisterSet::debugregs() { +#if defined(__powerpc__) + /* The DABR is 64-bit wide, even in powerpc32. */ + return new frysk::sys::ptrace::RegisterSet(sizeof(long long), + PTRACE_GET_DEBUGREG, + PTRACE_SET_DEBUGREG); +#else + return NULL; +#endif +} + +frysk::sys::ptrace::RegisterSet* +frysk::sys::ptrace::RegisterSet::siginfo() { + return new frysk::sys::ptrace::RegisterSet(sizeof(siginfo_t), + PTRACE_GETSIGINFO, + PTRACE_SETSIGINFO); +}