public inbox for frysk-cvs@sourceware.org help / color / mirror / Atom feed
From: pmuldoon@sourceware.org To: frysk-cvs@sourceware.org Subject: [SCM] master: 2008-03-28 Phil Muldoon <pmuldoon@redhat.com> Date: Fri, 28 Mar 2008 14:56:00 -0000 [thread overview] Message-ID: <20080328145630.18231.qmail@sourceware.org> (raw) The branch, master has been updated via f420379d810861961ed40f40544c75124f9701b5 (commit) from 8ad1844bae3c034520abfb564d1a37d9b7ea933a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit f420379d810861961ed40f40544c75124f9701b5 Author: Phil Muldoon <pmuldoon@redhat.com> Date: Fri Mar 28 14:55:48 2008 +0000 2008-03-28 Phil Muldoon <pmuldoon@redhat.com> * Watchpoint.java: New. Initial Implementation. * WatchpointFactory.java: Ditto. * IA32Watchpoint.java: Ditto. * X8664Watchpoint.java: Ditto. * TestWatchpoint.java: Ditto. * package.html: Ditto. ----------------------------------------------------------------------- Summary of changes: frysk-core/frysk/isa/watchpoints/ChangeLog | 16 ++ .../frysk/isa/watchpoints/IA32Watchpoint.java | 214 +++++++++++++++++++ .../frysk/isa/watchpoints/TestWatchpoint.java | 224 ++++++++++++++++++++ .../watchpoints/Watchpoint.java} | 108 ++++------ .../watchpoints/WatchpointFactory.java} | 23 ++- .../frysk/isa/watchpoints/X8664Watchpoint.java | 209 ++++++++++++++++++ frysk-core/frysk/isa/watchpoints/package.html | 12 + 7 files changed, 735 insertions(+), 71 deletions(-) create mode 100644 frysk-core/frysk/isa/watchpoints/ChangeLog create mode 100644 frysk-core/frysk/isa/watchpoints/IA32Watchpoint.java create mode 100644 frysk-core/frysk/isa/watchpoints/TestWatchpoint.java copy frysk-core/frysk/{sysroot/SysRootCache.java => isa/watchpoints/Watchpoint.java} (53%) copy frysk-core/frysk/{testbed/TestStatState.java => isa/watchpoints/WatchpointFactory.java} (84%) create mode 100644 frysk-core/frysk/isa/watchpoints/X8664Watchpoint.java create mode 100644 frysk-core/frysk/isa/watchpoints/package.html First 500 lines of diff: diff --git a/frysk-core/frysk/isa/watchpoints/ChangeLog b/frysk-core/frysk/isa/watchpoints/ChangeLog new file mode 100644 index 0000000..0e4f56f --- /dev/null +++ b/frysk-core/frysk/isa/watchpoints/ChangeLog @@ -0,0 +1,16 @@ +2008-03-28 Phil Muldoon <pmuldoon@redhat.com> + + * Watchpoint.java: New. Initial Implementation. + * WatchpointFactory.java: Ditto. + * IA32Watchpoint.java: Ditto. + * X8664Watchpoint.java: Ditto. + * TestWatchpoint.java: Ditto. + * package.html: Ditto. + +\f +Local Variables: +mode: change-log +left-margin: 8 +fill-column: 74 +version-control: never +End: diff --git a/frysk-core/frysk/isa/watchpoints/IA32Watchpoint.java b/frysk-core/frysk/isa/watchpoints/IA32Watchpoint.java new file mode 100644 index 0000000..3627d03 --- /dev/null +++ b/frysk-core/frysk/isa/watchpoints/IA32Watchpoint.java @@ -0,0 +1,214 @@ +// This file is part of the program FRYSK. +// +// Copyright 2005, 2006, 2007, 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.IA32Registers; +import frysk.proc.Task; + +class IA32Watchpoint extends Watchpoint { + + // Architecture Watchpoint Count. Number of usable + // Address-Breakpoint Registers (DR0-DR3) + public IA32Watchpoint () { + noOfWatchpoints = 4; + } + + /** + * Builds and sets a hardware watchpoint on a task. + * + * @param task - task to set a watchpoint on. + * @param index - watchpoint number to write. Architecture + * dependent. + * @param addr - linear virtual address to watch. + * @param range - length of range to watch. Normally + * 1,2 or 4 bytes. + * @param writeOnly - When true, only trigger when address is + * written. False, trigger when address is read or written to. + * @param localOnly - set local extant only. + */ + public void setWatchpoint(Task task, int index, + long addr, int range, + boolean writeOnly, + boolean localOnly) { + + + // turn bit off (b = bit no): l &= ~(1L << b) + // turn bit on ( b= bit no): l |= (1L << b); + if ((range == 1) || (range == 2) || (range == 4)) { + + // Set the Debug register with the linear address. + task.setRegister(IA32Registers.DEBUG_REGS_GROUP.getRegisters()[index], + addr); + // Get the Debug Control Register + long debugControl = task.getRegister(IA32Registers.DEBUG_CONTROL); + + // First eight bits of register define the global/local + // status of each of the four DR registers. Two bits per + // register + + // Calculate "Global Exact Breakpoint #index Enabled" bit to set + int bitToSet = index * 2; + + if (localOnly) { + // Set "Local Exact Breakpoint #index Enabled" to 0 + debugControl |= (1L << bitToSet); + // Set Global Exact Breakpoint to 1 + debugControl &= ~(1L << bitToSet+1); + } else { + // Set "Local Exact Breakpoint #index Enabled" to 0 + debugControl &= ~(1L << bitToSet); + // Set Global Exact Breakpoint to 1 + debugControl |= (1L << bitToSet+1); + } + + // Dending on the WP register to set, the next + // 4 bits are offset 4 * WP Count. On x8664 + // the control bits for DR0 start at bit 16, + // DR1 at 20 and so on. + + // The next four bits are as follows: + + // Set watchpoint to read/write detection + // bits 11 = read/write. bits 01 = write only. + int typeOfWpTrap = 16 + (index *4); + + + if (writeOnly) { + debugControl |= (1L << typeOfWpTrap); + debugControl &= ~(1L << typeOfWpTrap+1); + } else { + debugControl |= (1L << typeOfWpTrap); + debugControl |= (1L << typeOfWpTrap+1); + } + + // Set watch point length + // 00 = 1 byte, 01 = 2 bytes, 11 = 4 bytes + // 10 = 8 bytes + int length = typeOfWpTrap + 2; + switch (range) { + case 1: + debugControl &= ~(1L << length); + debugControl &= ~(1L << length+1); + break; + case 2: + debugControl &= ~(1L << length); + debugControl |= (1L << length+1); + break; + case 4: + debugControl |=(1L << length); + debugControl |= (1L << length+1); + break; + case 8: + debugControl |= (1L << length); + debugControl &= ~(1L << length+1); + break; + } + + task.setRegister(IA32Registers.DEBUG_CONTROL, debugControl); + } + else + throw new RuntimeException("Invalid size for watchpoint " + + "range. Has to be 1, 2, 4 or 8"); + } + + /** + * Reads a watchpoint. Takes a task, and an index. + * + * @param task - task to read a watchpoint from. + * @param index - watchpoint number to read. + * + * @return long - value of register for watchpoint. + */ + public long readWatchpoint(Task task, int index) { + return task.getRegister(IA32Registers.DEBUG_REGS_GROUP.getRegisters()[index]); + } + + /** + * 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) { + // Set the Debug register with the linear address. + task.setRegister(IA32Registers.DEBUG_REGS_GROUP.getRegisters()[index], + 0x0L); + // Get the Debug Control Register + long debugControl = task.getRegister(IA32Registers.DEBUG_CONTROL); + + // First eight bits of register define the global/local + // status of each of the four DR registers. Two bits per + // register + + // Calculate "Global Exact Breakpoint #index Enabled" bit to set + int bitToSet = index * 2; + + // Clear all register bits to 0 + debugControl &= ~(1L << bitToSet); + debugControl &= ~(1L << bitToSet+1); + + int typeOfWpTrap = 16 + (index *4); + debugControl &= ~(1L << typeOfWpTrap); + debugControl &= ~(1L << typeOfWpTrap+1); + + int length = typeOfWpTrap + 2; + debugControl &= ~(1L << length); + debugControl &= ~(1L << length+1); + + task.setRegister(IA32Registers.DEBUG_CONTROL, debugControl); + } + + + + /** + * Reads the Debug control register. + * + * @param task - task to read the debug control + * register from. + */ + public long readControlRegister(Task task) { + return task.getRegister(IA32Registers.DEBUG_CONTROL); + } + +} + + diff --git a/frysk-core/frysk/isa/watchpoints/TestWatchpoint.java b/frysk-core/frysk/isa/watchpoints/TestWatchpoint.java new file mode 100644 index 0000000..e218689 --- /dev/null +++ b/frysk-core/frysk/isa/watchpoints/TestWatchpoint.java @@ -0,0 +1,224 @@ +// 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.proc.Proc; +import frysk.proc.Task; +import frysk.testbed.DaemonBlockedAtEntry; +import frysk.testbed.TestLib; +public class TestWatchpoint extends TestLib { + + + public void testWatchFourBytesBitPattern() { + // Test Four byte bit pattern in a cumulative fasion + // across all WP registers. Assume global exact and + // read/write bit is set. At end, delete all watchpoints + // and ensure debug control register is as we found it. + if (unresolvedOnPPC(5991)) + return; + Proc proc = giveMeABlockedProc(); + Task task = proc.getMainTask(); + long address = 0x1000; + long debugControlRegister; + Watchpoint wp = WatchpointFactory.getWatchpoint(task.getISA()); + long savedDebugControlRegister = wp.readControlRegister(task); + for (int i=0; i<4; i++) { + + + wp.setWatchpoint(task, i, address, 4, false, false); + // simple first test. Does register contain address? + assertEquals("Saved watchpoint and address are similar", + address, wp.readWatchpoint(task, i)); + + debugControlRegister = wp.readControlRegister(task); + + // Test Debug Control Register Bit Pattern. Global Exact. + assertEquals(i + " wp local exact bit", false, + testBit(debugControlRegister, 0 + (i*2))); + assertEquals(i + " wp global exact bit", true, + testBit(debugControlRegister, 1 + (i*2))); + + // Test Debug Control Register. Fire on Read and Write + assertEquals(i + "wp r/w bit 0", true, + testBit(debugControlRegister, 16 + (i * 4))); + assertEquals(i + "wp r/w bit 1 ", true, + testBit(debugControlRegister, 17 + (i * 4))); + + // Test Debug Control Register. Test Length four bytes. + assertEquals(i +"wp length bit 0", true, + testBit(debugControlRegister, 18 + (i * 4))); + assertEquals(i + "wo length bit 1", true , + testBit(debugControlRegister, 19 + (i * 4))); + } + + for (int j=0; j < 4; j++) { + wp.deleteWatchpoint(task,j); + assertEquals("Deleted Watchpoint is 0", + wp.readWatchpoint(task, j),0); + } + + assertEquals("Debug control register is left as we originally found it", + savedDebugControlRegister,wp.readControlRegister(task)); + + } + + public void testWatchOneByteBitPattern() { + // Test One byte bit pattern in a cumulative fasion + // across all WP registers. Assume global exact and + // read/write bit is set. At end, delete all watchpoints + // and ensure debug control register is as we found it. + if (unresolvedOnPPC(5991)) + return; + Proc proc = giveMeABlockedProc(); + Task task = proc.getMainTask(); + long address = 0x1000; + long debugControlRegister; + Watchpoint wp = WatchpointFactory.getWatchpoint(task.getISA()); + long savedDebugControlRegister = wp.readControlRegister(task); + for (int i=0; i<4; i++) { + + + wp.setWatchpoint(task, i, address, 1, true, false); + // simple first test. Does register contain address? + assertEquals("Saved watchpoint and address are similar", + address, wp.readWatchpoint(task, i)); + + debugControlRegister = wp.readControlRegister(task); + + // Test Debug Control Register Bit Pattern. Global Exact. + assertEquals(i + " wp local exact bit", false, + testBit(debugControlRegister, 0 + (i*2))); + assertEquals(i + " wp global exact bit", true, + testBit(debugControlRegister, 1 + (i*2))); + + // Test Debug Control Register. Fire on Read and Write + assertEquals(i + "wp r/w bit 0", true, + testBit(debugControlRegister, 16 + (i * 4))); + assertEquals(i + "wp r/w bit 1 ", false, + testBit(debugControlRegister, 17 + (i * 4))); + + // Test Debug Control Register. Test Length four bytes. + assertEquals(i +"wp length bit 0", false, + testBit(debugControlRegister, 18 + (i * 4))); + assertEquals(i + "wo length bit 1", false, + testBit(debugControlRegister, 19 + (i * 4))); + } + + for (int j=0; j < 4; j++) { + wp.deleteWatchpoint(task,j); + assertEquals("Deleted Watchpoint is 0", + wp.readWatchpoint(task, j),0); + } + + assertEquals("Debug control register is left as we originally found it", + savedDebugControlRegister,wp.readControlRegister(task)); + + } + + + public void testWatchTwoByteBitPattern() { + // Test two byte bit pattern AND test local exact only. + // Test bit pattern in a cumulative fasion + // across all WP registers. Assume local exact and + // but read/write bit is set. At end, delete all watchpoints + // and ensure debug control register is as we found it. + if (unresolvedOnPPC(5991)) + return; + Proc proc = giveMeABlockedProc(); + Task task = proc.getMainTask(); + long address = 0x0; + long debugControlRegister; + Watchpoint wp = WatchpointFactory.getWatchpoint(task.getISA()); + long savedDebugControlRegister = wp.readControlRegister(task); + + for (int i=0; i<4; i++) { + wp.setWatchpoint(task, i, address, 1, false, true); + + // simple first test. Does register contain address? + assertEquals("Saved watchpoint and address are similar", + address, wp.readWatchpoint(task, i)); + + debugControlRegister = wp.readControlRegister(task); + + // Test Debug Control Register Bit Pattern. Local Exact. + assertEquals(i + " wp local exact bit", true, + testBit(debugControlRegister, 0 + (i*2))); + assertEquals(i + " wp global exact bit", false, + testBit(debugControlRegister, 1 + (i*2))); + + // Test Debug Control Register. Fire on Read and Write + assertEquals(i + "wp r/w bit 0", true, + testBit(debugControlRegister, 16 + (i * 4))); + assertEquals(i + "wp r/w bit 1 ", true, + testBit(debugControlRegister, 17 + (i * 4))); + + // Test Debug Control Register. Test Length four bytes. + assertEquals(i +"wp length bit 0", false, + testBit(debugControlRegister, 18 + (i * 4))); + assertEquals(i + "wo length bit 1", false , + testBit(debugControlRegister, 19 + (i * 4))); + } + + for (int j=0; j < 4; j++) { + wp.deleteWatchpoint(task,j); + assertEquals("Deleted Watchpoint is 0", + wp.readWatchpoint(task, j),0); + } + + assertEquals("Debug control register is left as we originally found it", + savedDebugControlRegister,wp.readControlRegister(task)); + + } + + private boolean testBit(long register, int bitToTest) { + return (register & (1L << bitToTest)) != 0; + } + + private Proc giveMeABlockedProc () + { + String[] nocmds = {}; + DaemonBlockedAtEntry ackProc = new DaemonBlockedAtEntry(nocmds); + assertNotNull(ackProc); + return ackProc.getMainTask().getProc(); + } + +} + diff --git a/frysk-core/frysk/sysroot/SysRootCache.java b/frysk-core/frysk/isa/watchpoints/Watchpoint.java similarity index 53% copy from frysk-core/frysk/sysroot/SysRootCache.java copy to frysk-core/frysk/isa/watchpoints/Watchpoint.java index 1057198..fc8c234 100644 --- a/frysk-core/frysk/sysroot/SysRootCache.java +++ b/frysk-core/frysk/isa/watchpoints/Watchpoint.java @@ -1,4 +1,5 @@ // 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 @@ -36,84 +37,69 @@ // version and license this file solely under the GPL without // exception. -package frysk.sysroot; +package frysk.isa.watchpoints; -import java.io.File; -import java.util.WeakHashMap; import frysk.proc.Task; -/** - * Map from a Task's executable to its special root directory. - */ hooks/post-receive -- frysk system monitor/debugger
reply other threads:[~2008-03-28 14:56 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20080328145630.18231.qmail@sourceware.org \ --to=pmuldoon@sourceware.org \ --cc=frysk-cvs@sourceware.org \ --cc=frysk@sourceware.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).