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
setpcs(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
msgpcs(char * msg)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
unloadnote(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
loadnote(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
notes(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
killpcs(void)115 killpcs(void)
116 {
117 msgpcs("kill");
118 }
119
120 void
grab(void)121 grab(void)
122 {
123 flush();
124 msgpcs("stop");
125 bpwait();
126 }
127
128 void
ungrab(void)129 ungrab(void)
130 {
131 msgpcs("start");
132 }
133
134 void
doexec(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
startpcs(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
runstep(uvlong loc,int keepnote)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
bpwait(void)237 bpwait(void)
238 {
239 setcor();
240 unloadnote();
241 }
242
243 void
runrun(int keepnote)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
bkput(BKPT * bp,int install)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 }
287