]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/db/trcrun.c
9bootfat: rename open() to fileinit and make it static as its really a internal funct...
[plan9front.git] / sys / src / cmd / db / trcrun.c
1 /*
2  * functions for running the debugged process
3  */
4
5 #include "defs.h"
6 #include "fns.h"
7
8
9 int child;
10 int msgfd = -1;
11 int notefd = -1;
12 int pcspid = -1;
13 int pcsactive = 0;
14
15 void
16 setpcs(void)
17 {
18         char buf[128];
19
20         if(pid && pid != pcspid){
21                 if(msgfd >= 0){
22                         close(msgfd);
23                         msgfd = -1;
24                 }
25                 if(notefd >= 0){
26                         close(notefd);
27                         notefd = -1;
28                 }
29                 pcspid = -1;
30                 sprint(buf, "/proc/%d/ctl", pid);
31                 msgfd = open(buf, OWRITE);
32                 if(msgfd < 0)
33                         error("can't open control file");
34                 sprint(buf, "/proc/%d/note", pid);
35                 notefd = open(buf, ORDWR);
36                 if(notefd < 0)
37                         error("can't open note file");
38                 pcspid = pid;
39         }
40 }
41
42 void
43 msgpcs(char *msg)
44 {
45         char err[ERRMAX];
46
47         setpcs();
48         if(write(msgfd, msg, strlen(msg)) < 0 && !ending){
49                 errstr(err, sizeof err);
50                 if(strcmp(err, "interrupted") != 0)
51                         endpcs();
52                 errors("can't write control file", err);
53         }
54 }
55
56 /*
57  * empty the note buffer and toss pending breakpoint notes
58  */
59 void
60 unloadnote(void)
61 {
62         char err[ERRMAX];
63
64         setpcs();
65         for(; nnote<NNOTE; nnote++){
66                 switch(read(notefd, note[nnote], sizeof note[nnote])){
67                 case -1:
68                         errstr(err, sizeof err);
69                         if(strcmp(err, "interrupted") != 0)
70                                 endpcs();
71                         errors("can't read note file", err);
72                 case 0:
73                         return;
74                 }
75                 note[nnote][ERRMAX-1] = '\0';
76                 if(strncmp(note[nnote], "sys: breakpoint", 15) == 0)
77                         --nnote;
78         }
79 }
80
81 /*
82  * reload the note buffer
83  */
84 void
85 loadnote(void)
86 {
87         int i;
88         char err[ERRMAX];
89
90         setpcs();
91         for(i=0; i<nnote; i++){
92                 if(write(notefd, note[i], strlen(note[i])) < 0){
93                         errstr(err, sizeof err);
94                         if(strcmp(err, "interrupted") != 0)
95                                 endpcs();
96                         errors("can't write note file", err);
97                 }
98         }
99         nnote = 0;
100 }
101
102 void
103 notes(void)
104 {
105         int n;
106
107         if(nnote == 0)
108                 return;
109         dprint("notes:\n");
110         for(n=0; n<nnote; n++)
111                 dprint("%d:\t%s\n", n, note[n]);
112 }
113
114 void
115 killpcs(void)
116 {
117         msgpcs("kill");
118 }
119
120 void
121 grab(void)
122 {
123         flush();
124         msgpcs("stop");
125         bpwait();
126 }
127
128 void
129 ungrab(void)
130 {
131         msgpcs("start");
132 }
133
134 void
135 doexec(void)
136 {
137         char *argl[MAXARG];
138         char args[LINSIZ];
139         char *p;
140         char **ap;
141         char *thisarg;
142
143         ap = argl;
144         p = args;
145         *ap++ = symfil;
146         for (rdc(); lastc != EOR;) {
147                 thisarg = p;
148                 if (lastc == '<' || lastc == '>') {
149                         *p++ = lastc;
150                         rdc();
151                 }
152                 while (lastc != EOR && lastc != SPC && lastc != TB) {
153                         *p++ = lastc;
154                         readchar();
155                 }
156                 if (lastc == SPC || lastc == TB)
157                         rdc();
158                 *p++ = 0;
159                 if (*thisarg == '<') {
160                         close(0);
161                         if (open(&thisarg[1], OREAD) < 0) {
162                                 print("%s: cannot open\n", &thisarg[1]);
163                                 _exits(0);
164                         }
165                 }
166                 else if (*thisarg == '>') {
167                         close(1);
168                         if (create(&thisarg[1], OWRITE, 0666) < 0) {
169                                 print("%s: cannot create\n", &thisarg[1]);
170                                 _exits(0);
171                         }
172                 }
173                 else
174                         *ap++ = thisarg;
175         }
176         *ap = 0;
177         exec(symfil, argl);
178         perror(symfil);
179 }
180
181 char    procname[100];
182
183 void
184 startpcs(void)
185 {
186         if ((pid = fork()) == 0) {
187                 pid = getpid();
188                 msgpcs("hang");
189                 doexec();
190                 exits(0);
191         }
192
193         if (pid == -1)
194                 error("can't fork");
195         child++;
196         sprint(procname, "/proc/%d/mem", pid);
197         corfil = procname;
198         msgpcs("waitstop");
199         bpwait();
200         if (adrflg)
201                 rput(cormap, mach->pc, adrval);
202         while (rdc() != EOR)
203                 ;
204         reread();
205 }
206
207 void
208 runstep(uvlong loc, int keepnote)
209 {
210         int nfoll;
211         uvlong foll[3];
212         BKPT bkpt[3];
213         int i;
214
215         if(machdata->foll == 0){
216                 dprint("stepping unimplemented; assuming not a branch\n");
217                 nfoll = 1;
218                 foll[0] = loc+mach->pcquant;
219         }else {
220                 nfoll = machdata->foll(cormap, loc, rget, foll);
221                 if (nfoll < 0)
222                         error("%r");
223         }
224         memset(bkpt, 0, sizeof bkpt);
225         for(i=0; i<nfoll; i++){
226                 if(foll[i] == loc)
227                         error("can't single step: next instruction is dot");
228                 bkpt[i].loc = foll[i];
229                 bkput(&bkpt[i], 1);
230         }
231         runrun(keepnote);
232         for(i=0; i<nfoll; i++)
233                 bkput(&bkpt[i], 0);
234 }
235
236 void
237 bpwait(void)
238 {
239         setcor();
240         unloadnote();
241 }
242
243 void
244 runrun(int keepnote)
245 {
246         int on;
247
248         on = nnote;
249         unloadnote();
250         if(on != nnote){
251                 notes();
252                 error("not running: new notes pending");
253         }
254         if(keepnote)
255                 loadnote();
256         else
257                 nnote = 0;
258         flush();
259         msgpcs("startstop");
260         bpwait();
261 }
262
263 void
264 bkput(BKPT *bp, int install)
265 {
266         char buf[256];
267         ADDR loc;
268         int ret;
269
270         errstr(buf, sizeof buf);
271         if(machdata->bpfix)
272                 loc = (*machdata->bpfix)(bp->loc);
273         else
274                 loc = bp->loc;
275         if(install){
276                 ret = get1(cormap, loc, bp->save, machdata->bpsize);
277                 if (ret > 0)
278                         ret = put1(cormap, loc, machdata->bpinst, machdata->bpsize);
279         }else
280                 ret = put1(cormap, loc, bp->save, machdata->bpsize);
281         if(ret < 0){
282                 sprint(buf, "can't set breakpoint at %#llux: %r", bp->loc);
283                 print(buf);
284                 read(0, buf, 100);
285         }
286 }