summaryrefslogtreecommitdiff
path: root/sys/lib/acid
diff options
context:
space:
mode:
authoraiju <devnull@localhost>2017-06-12 19:29:20 +0000
committeraiju <devnull@localhost>2017-06-12 19:29:20 +0000
commit68cfc786ba6f956cb7e1210ee312f436ae69192b (patch)
tree20fcb2c38b39b2deb2135d4a4a9a7891f77fe526 /sys/lib/acid
parent5dcb407add4013d7234dc248fb97c8a5d146e3d3 (diff)
acid: watchpoint support
Diffstat (limited to 'sys/lib/acid')
-rw-r--r--sys/lib/acid/38613
-rw-r--r--sys/lib/acid/680202
-rw-r--r--sys/lib/acid/amd6415
-rw-r--r--sys/lib/acid/arm2
-rw-r--r--sys/lib/acid/mips2
-rw-r--r--sys/lib/acid/port145
-rw-r--r--sys/lib/acid/power2
-rw-r--r--sys/lib/acid/sparc2
-rw-r--r--sys/lib/acid/sparc642
9 files changed, 178 insertions, 7 deletions
diff --git a/sys/lib/acid/386 b/sys/lib/acid/386
index 5ae46fd83..fb7a8ad29 100644
--- a/sys/lib/acid/386
+++ b/sys/lib/acid/386
@@ -4,6 +4,8 @@ defn acidinit() // Called after all the init modules are loaded
{
bplist = {};
bpfmt = 'b';
+ wplist = {};
+ wpflush();
srcpath = {
"./",
@@ -84,13 +86,18 @@ defn pstop(pid)
local l;
local pc;
- pc = *PC;
+ pc = (*PC)\i;
+
+ if notes && regexp("^sys: watchpoint ", notes[0]) then
+ pc--;
print(pid,": ", reason(*TRAP), "\t");
- print(fmt(pc, 'a'), "\t", fmt(pc, 'i'), "\n");
+ print(fmt(pc, 'a'), "\t", pc, "\n");
if notes then {
- if notes[0] != "sys: breakpoint" then {
+ if regexp("^sys: watchpoint ", notes[0]) then
+ wpprocess();
+ else if notes[0] != "sys: breakpoint" then {
print("Notes pending:\n");
l = notes;
while l do {
diff --git a/sys/lib/acid/68020 b/sys/lib/acid/68020
index 4d19b0fb6..ae02d101e 100644
--- a/sys/lib/acid/68020
+++ b/sys/lib/acid/68020
@@ -4,6 +4,8 @@ defn acidinit() // Called after all the init modules are loaded
{
bplist = {};
bpfmt = 'x';
+ wplist = {};
+ wpflush();
srcpath = {
"./",
diff --git a/sys/lib/acid/amd64 b/sys/lib/acid/amd64
index 7d7ce4ba7..9a850cfca 100644
--- a/sys/lib/acid/amd64
+++ b/sys/lib/acid/amd64
@@ -4,7 +4,9 @@ defn acidinit()
{
bplist = {};
bpfmt = 'b';
-
+ wplist = {};
+ wpflush();
+
srcpath = {
"./",
"/sys/src/libc/port/",
@@ -98,13 +100,18 @@ defn pstop(pid)
local l;
local pc;
- pc = *PC;
+ pc = (*PC)\i;
+
+ if notes && regexp("^sys: watchpoint ", notes[0]) then
+ pc--;
print(pid,": ", reason(*TRAP), "\t");
- print(fmt(pc, 'a'), "\t", fmt(pc, 'i'), "\n");
+ print(fmt(pc, 'a'), "\t", pc, "\n");
if notes then {
- if notes[0] != "sys: breakpoint" then {
+ if regexp("^sys: watchpoint ", notes[0]) then
+ wpprocess();
+ else if notes[0] != "sys: breakpoint" then {
print("Notes pending:\n");
l = notes;
while l do {
diff --git a/sys/lib/acid/arm b/sys/lib/acid/arm
index 0578da53f..18f88cf33 100644
--- a/sys/lib/acid/arm
+++ b/sys/lib/acid/arm
@@ -4,6 +4,8 @@ defn acidinit() // Called after all the init modules are loaded
{
bplist = {};
bpfmt = 'X';
+ wplist = {};
+ wpflush();
srcpath = {
"./",
diff --git a/sys/lib/acid/mips b/sys/lib/acid/mips
index 5c267d1f0..79968b93f 100644
--- a/sys/lib/acid/mips
+++ b/sys/lib/acid/mips
@@ -4,6 +4,8 @@ defn acidinit() // Called after all the init modules are loaded
{
bplist = {};
bpfmt = 'X';
+ wplist = {};
+ wpflush();
srcpath = {
"./",
diff --git a/sys/lib/acid/port b/sys/lib/acid/port
index 60cfa1adc..aa48ef3e7 100644
--- a/sys/lib/acid/port
+++ b/sys/lib/acid/port
@@ -267,6 +267,7 @@ defn step() // single step the process
bput = fmt(*PC, bpfmt);
*bput = @bput;
}
+ wpupdate(0);
lst = follow(*PC);
@@ -336,6 +337,134 @@ defn bpdel(addr) // delete a breakpoint
bplist = nbplist; // delete from memory
}
+defn wpflush() // copy wplist to /proc/$pid/watchpt
+{
+ local s, lst, el;
+
+ lst = wplist;
+ s = "";
+ while lst do {
+ el = head lst;
+ s = s + (el[0] + " " + itoa(el[1]) + " " + itoa(el[2]) + "\n");
+ lst = tail lst;
+ }
+ lst = proclist;
+ while lst do {
+ if access("/proc/"+itoa(head lst)+"/watchpt") then
+ printto("/proc/"+itoa(head lst)+"/watchpt", s);
+ lst = tail lst;
+ }
+}
+
+defn wpset(type, addr, len) // set a watchpoint
+{
+ local lst;
+
+ if status(pid) != "Stopped" then {
+ print("Waiting...\n");
+ stop(pid);
+ }
+ if !regexp("^[rwx\\-]+$", type) then {
+ print("invalid type\n");
+ return {};
+ }
+ lst = proclist;
+ while lst do {
+ if rc("echo '"+type+" "+itoa(addr)+" "+itoa(len)+"' >> /proc/"+itoa(head lst)+"/watchpt") != "" then
+ return {};
+ lst = tail lst;
+ }
+ wplist = append wplist, {type, addr, len, {}};
+}
+
+defn wptab() // print a table of watchpoints
+{
+ local lst, el;
+
+ lst = wplist;
+ while lst do {
+ el = head lst;
+ print("\t", el[0], " ", fmt(el[1], 'A'), " ", fmt(el[1], 'a'), " ", fmt(el[2], 'd'), "\n");
+ lst = tail lst;
+ }
+}
+
+defn wpdel(addr)
+{
+ local lst, el, found, nwplist;
+
+ lst = wplist;
+ found = 0;
+ nwplist = {};
+ while lst do {
+ el = head lst;
+ if el[1] == addr then
+ found = 1;
+ else
+ nwplist = append nwplist, el;
+ lst = tail lst;
+ }
+ if found == 0 then {
+ print("no watchpoint at ", fmt(addr, 'a'), "\n");
+ return {};
+ }
+ wplist = nwplist;
+ wpflush();
+}
+
+defn bytes(b)
+{
+ local s;
+
+ s = "";
+ while b do {
+ s = s + itoa(head b, "%#.2x ");
+ b = tail b;
+ }
+ return s;
+}
+
+defn wpupdate(ch) // update remembered values
+{
+ local el, nwplist, mem, lst, i;
+
+ lst = wplist;
+ nwplist = {};
+ while lst do {
+ el = head lst;
+ i = 0;
+ mem = {};
+ while i < el[2] do {
+ mem = append mem, *((el[1] + i)\b);
+ i = i + 1;
+ }
+ if ch && el[3] != {} && el[3] != mem then {
+ print("\t", fmt(el[1], 'a'), "\twas ", bytes(el[3]), "\n");
+ print("\t", fmt(el[1], 'a'), "\tis ", bytes(mem), "\n");
+ }
+ nwplist = append nwplist, {el[0], el[1], el[2], mem};
+ lst = tail lst;
+ }
+ wplist = nwplist;
+}
+
+defn wpprocess() // trapped at watchpoint
+{
+ local pts;
+ local el;
+
+ pts = getfields(getfields(notes[0], " ", 1)[2], ",", 1);
+ while pts do {
+ el = head pts;
+ el = wplist[atoi(el)];
+ if el != {} then {
+ print("\ttriggered ", el[0], " watchpoint at ", fmt(el[1], 'a'), " (", fmt(el[1], 'A'), ")\n");
+ }
+ pts = tail pts;
+ }
+ wpupdate(1);
+}
+
defn cont() // continue execution
{
local addr;
@@ -346,6 +475,7 @@ defn cont() // continue execution
step(); // Step over
*addr = bpinst;
}
+ wpupdate(0);
startstop(pid); // Run
}
@@ -405,6 +535,7 @@ defn win()
local npid, estr;
bplist = {};
+ wplist = {};
notes = {};
estr = "/sys/lib/acid/window '0 0 600 400' "+textfile;
@@ -425,6 +556,7 @@ defn win2()
local npid, estr;
bplist = {};
+ wplist = {};
notes = {};
estr = "/sys/lib/acid/transcript '0 0 600 400' '100 100 700 500' "+textfile;
@@ -443,6 +575,7 @@ defn win2()
defn new()
{
bplist = {};
+ wplist = {};
newproc(progargs);
// Dont miss the delay slot calls
bpset(follow(main)[0]);
@@ -565,5 +698,17 @@ defn spsrch(len)
}
}
+defn procattach()
+{
+ wpflush();
+}
+
+defn dying()
+{
+ wplist = {};
+ wpflush();
+ derp();
+}
+
progargs="";
print("/sys/lib/acid/port");
diff --git a/sys/lib/acid/power b/sys/lib/acid/power
index 68aeacb18..6be4992b9 100644
--- a/sys/lib/acid/power
+++ b/sys/lib/acid/power
@@ -4,6 +4,8 @@ defn acidinit() // Called after all the init modules are loaded
{
bplist = {};
bpfmt = 'X';
+ wplist = {};
+ wpflush();
srcpath = {
"./",
diff --git a/sys/lib/acid/sparc b/sys/lib/acid/sparc
index 76a1eba36..246d553b8 100644
--- a/sys/lib/acid/sparc
+++ b/sys/lib/acid/sparc
@@ -4,6 +4,8 @@ defn acidinit() // Called after all the init modules are loaded
{
bplist = {};
bpfmt = 'X';
+ wplist = {};
+ wpflush();
srcpath = {
"./",
diff --git a/sys/lib/acid/sparc64 b/sys/lib/acid/sparc64
index f1710bd86..2abb5fe14 100644
--- a/sys/lib/acid/sparc64
+++ b/sys/lib/acid/sparc64
@@ -4,6 +4,8 @@ defn acidinit() // Called after all the init modules are loaded
{
bplist = {};
bpfmt = 'X';
+ wplist = {};
+ wpflush();
srcpath = {
"./",