|
|
1.1 root 1: #include "process.pub"
2: #include "frame.pri"
3: #include "symtab.pri"
4: #include "symbol.h"
5: #include "hostcore.h"
6: #include <a.out.h>
7: #include "asm.pri"
8: #include "format.pub"
9: #include "bpts.pri"
10: #include "master.pri"
11: #include <machine/vmparam.h>
12: SRCFILE("hostcore.c")
13: #define TXTOFF(magic) (magic==ZMAGIC ? 0 : sizeof (struct exec))
14:
15: Behavs HostCore::behavetype() { return behavs(); }
16: char *HostCore::eventname() { return SignalName(event()); }
17: char *HostCore::run() { return ioctl(PIOCRUN); }
18: char *HostCore::stop() { return sendsig(SIGSTOP); }
19: int HostCore::event() { return pr.p_cursig; }
20: long HostCore::scratchaddr() { return 0x2000; }
21:
22: long HostCore::regaddr()
23: {
24: return (long)u()->u_ar0;
25: }
26:
27: #define SUNBPT 0x4e4f /* Trap #15 */
28: char *HostCore::laybpt(Trap *t)
29: {
30: t->saved = peek(t->stmt->range.lo)->sht;
31: return poke(t->stmt->range.lo, SUNBPT, 2);
32: }
33:
34: Behavs HostCore::behavs()
35: {
36: if( !online() )
37: return PENDING;
38: char *error = readcontrol();
39: if( error ){
40: behavs_problem = sf( "readcontrol(): %s", error );
41: return ERRORED;
42: }
43: switch( pr.p_stat ){
44: case SSLEEP:
45: case SRUN:
46: return ACTIVE;
47: case SSTOP:
48: switch( pr.p_cursig ){
49: case SIGSTOP:
50: return HALTED;
51: case SIGTRAP:
52: return BREAKED;
53: default:
54: return PENDING;
55: }
56: }
57: behavs_problem = sf( "pr.p_stat=%d", pr.p_stat);
58: return ERRORED;
59: }
60:
61: char *HostCore::problem()
62: {
63: if( corefstat() )
64: return "core image has gone away";
65: return Core::problem();
66: }
67:
68: char *HostCore::readcontrol()
69: {
70: char *error;
71:
72: if( corefstat() )
73: return "cannot fstat core image";
74: if( online() ){
75: if( ::ioctl( corefd, PIOCGETPR, &pr ) < 0 )
76: return SysErr("fetching proc struct:");
77: if( error = read( USRADR, uarea(), ctob(UPAGES)) )
78: return error;
79: } else {
80: if( error = read( USRADR, uarea(), ctob(UPAGES)) )
81: return error;
82: pr = *(struct proc *)(uarea() + *(int *)u()->u_stack - UADDR);
83: }
84: return 0;
85: }
86:
87: char *HostCore::open()
88: {
89: int mode = 2;
90: while( procpath() && corefd<0 && mode>=0 )
91: corefd = ::open(procpath(), mode--);
92: if( procpath() && corefd<0 ) return SysErr("core image: " );
93: if( procpath() && corefstat() )
94: return SysErr("core image: " );
95: if( corestat.st_mode & S_IEXEC )
96: return "executable - should be process (/proc/123) or dump (core)";
97: if( stabpath() ){
98: stabfd = ::open(stabpath(),0);
99: if( stabfd<0 ) return SysErr( "symbol tables: " );
100: }
101: proc dummy_pr;
102: if( ::ioctl(corefd, PIOCGETPR, &dummy_pr) == 0 ){
103: _online = 1;
104: if( stabpath() == 0 )
105: stabfd = ::ioctl(corefd, PIOCOPENT, 0);
106: }
107: stabfstat();
108: _symtab = new Ed8SymTab(this, stabfd, _symtab);
109: _symtab->read();
110: return procpath() ? readcontrol() : 0;
111: }
112:
113: char *HostCore::reopen(char *newprocpath, char *newstabpath)
114: {
115: int mode = 2, newcorefd = -1, compstabfd = -1;
116:
117: while( newprocpath && newcorefd<0 && mode>=0 )
118: newcorefd = ::open(newprocpath, mode--);
119: if( newcorefd<0 )
120: return "cannot open process";
121: proc dummy_pr;
122: if( ::ioctl(newcorefd, PIOCGETPR, &dummy_pr) )
123: return "not a live process";
124: if( newstabpath )
125: compstabfd = ::open(newstabpath, 0);
126: else
127: compstabfd = ::ioctl(newcorefd, PIOCOPENT, 0);
128: struct stat compstabstat;
129: if( compstabfd < 0 || ::fstat(compstabfd, &compstabstat) ){
130: ::close(newcorefd);
131: return "symbol table error";
132: }
133: if( compstabstat.st_mtime != stabstat.st_mtime )
134: return "symbol tables differ (modified time)";
135: if( compstabstat.st_size != stabstat.st_size )
136: return "symbol tables differ (file size)";
137: ::close(corefd);
138: corefd = newcorefd;
139: ::close(compstabfd);
140: return readcontrol();
141: }
142:
143: #define ATTEMPTS 9 /* core file i/o */
144: #define SLEEP 2
145:
146: char *HostCore::seekto(int &fd, long &addr, int &whence)
147: {
148: long maxadr;
149:
150: if( !online() ) {
151: if( addr < 0x2000 )
152: return "offset below text segment";
153: else if( addr < (maxadr = ctob(u()->u_tsize + 1))) {
154: addr += TXTOFF(_symtab->magic()) - 0x2000;
155: fd = stabfd;
156: }
157: else if( addr < (maxadr = ctob(stoc(ctos(u()->u_tsize+1)))) )
158: return "offset below data segment";
159: else if( addr < (maxadr += ctob(u()->u_dsize)) ) {
160: addr = addr - (maxadr - ctob(u()->u_dsize))
161: + ctob(UPAGES);
162: }
163: else if( addr < (SYSADR - ctob(u()->u_ssize)) )
164: return "offset beyond data segment";
165: else if( addr < SYSADR )
166: { addr -= SYSADR; whence = 2; }
167: else if( addr >= USRADR )
168: addr -= USRADR;
169: else
170: return "offset in system space";
171: }
172: return 0;
173: }
174:
175: char *memcpy(char*,char*,int);
176:
177: char *HostCore::readwrite(long offset, char *buf, int r, int w)
178: {
179: int fd = corefd, whence = 0, attempts = ATTEMPTS;
180: extern int errno;
181: char *msg = "core image:";
182:
183: if( corefstat() )
184: return "core image fstat error";
185: char *error = seekto(fd, offset, whence);
186: if( error )
187: return sf("core image: %s", error);
188: while(--attempts>=0){
189: if( lseek(fd, offset, whence) == -1 )
190: return sf("lseek(%d,0x%X,%d)", fd, offset, whence);
191: if( r ){
192: int got = ::read(fd, buf, r);
193: for( int i = got; i < r; ++i ) buf[i] = 0;
194: if( got > 0 ) return 0;
195: }
196: if( w && ::write(fd, buf, w) == w ) return 0;
197: if( errno != EBUSY ) break;
198: if( online() ){
199: const SPRBUSY = (SLOCK|SSWAP|SPAGE|SKEEP|SDLYU|SWEXIT
200: |SVFORK|SVFDONE|SNOVM|SPROCIO);
201: msg = sf("core p_flag=0x%x: ", pr.p_flag);
202: if( !(pr.p_flag&SPRBUSY) ) break;
203: if( pr.p_flag&SPAGE ) ++attempts;
204: }
205: sleep(SLEEP);
206: }
207: return SysErr(msg);
208: }
209:
210: int HostCore::instack(long curfp, long prevfp )
211: {
212: return curfp < SYSADR && curfp > prevfp;
213: }
214:
215: int HostCore::fpvalid(long fp)
216: {
217: return instack(fp, 0x08000000);
218: }
219:
220: char *HostCore::ioctl(int p)
221: {
222: if( !online() )
223: return "process: not live";
224: if( ::ioctl( corefd, p, 0 )< 0 )
225: return SysErr( "process control: " );
226: return 0;
227: }
228:
229: char *HostCore::signalmask(long mask)
230: {
231: if( ::ioctl(corefd,PIOCSMASK,&mask)<0 )
232: return SysErr( "setting trace mask:" );
233: return 0;
234: }
235:
236: #define PSW_T 0x00008000
237: char *HostCore::pswT()
238: {
239: long ps = ((long *)(uarea() + (long)u()->u_ar0 - UADDR))[PS];
240: ps |= PSW_T;
241: return regpoke(REG_PS(), ps);
242: }
243:
244: static Alarm;
245: static void SigCatch(int)
246: {
247: extern int errno;
248: trace("SigCatch()");
249: Alarm = 1;
250: errno = 0;
251: }
252:
253: const int STEPWAIT = 15;
254:
255: char *HostCore::waitstop()
256: {
257: int oldalarm;
258: char *error = 0;
259:
260: oldalarm = alarm(STEPWAIT);
261: SIG_TYP oldsig = signal(SIGALRM, (SIG_ARG_TYP)&SigCatch);
262: Alarm = 0;
263: error = ioctl(PIOCWSTOP);
264: signal(SIGALRM, (SIG_ARG_TYP)oldsig);
265: alarm(oldalarm);
266: if( Alarm ){
267: ioctl(PIOCSTOP);
268: sleep(2);
269: return sf("timeout (%d secs)", STEPWAIT);
270: }
271: return error;
272: }
273:
274: const short M68K_TRAP0=0x4E40, M68K_RTS = 0x4E75;
275:
276: char *HostCore::dostep(long lo, long hi, int sstep)
277: {
278: char *error = 0;
279: long fp0, time0, time(long);
280:
281: time0 = ::time(0L);
282: fp0 = fp();
283: for(;;){
284: if( hi && isM68KJSB(peek(pc())->sht) ) {
285: error = stepoverM68KJSB();
286: goto next;
287: }
288: if (sstep)
289: error = pswT();
290: if( !error && (event()==SIGTRAP || event()==SIGSTOP) )
291: error = clrcurrsig();
292: if( !error ) error = run();
293: if( !error ) error = waitstop();
294: if( !error ) error = readcontrol();
295: if( !error && event()!=SIGTRAP )
296: error = sf( "single step error. signal=%d", event() );
297: if( !error ) error = clrcurrsig();
298: next:
299: if( error ) return error;
300: if( !hi || pc()<lo || pc()>=hi ||
301: (fp()>fp0 && peek(pc())->sht != M68K_RTS) )
302: return 0;
303: if( ::time(0L) > time0+STEPWAIT )
304: return sf("single step timeout (%d secs)",STEPWAIT);
305: }
306: }
307:
308: char *HostCore::resources()
309: {
310: static char buf[64];
311:
312: sprintf( buf, "%.1fu %.1fs",
313: (double)u()->u_vm.vm_utime/50, (double)u()->u_vm.vm_stime/50 );
314: return buf;
315: }
316:
317: void Wait3()
318: {
319: #define WNOHANG 1 /* see <wait.h> */
320: int wait3(int*,int,int*);
321: for( int i = 0; i<10 && wait3(0,WNOHANG,0)>0; ++i ) {} /* 10? */
322: }
323:
324: char *HostCore::destroy()
325: {
326: clrcurrsig();
327: char *error = sendsig(SIGKILL);
328: Wait3();
329: return error;
330: }
331:
332: char *HostCore::clrcurrsig()
333: {
334: char *error = ioctl(PIOCCSIG);
335: if( !error )
336: pr.p_cursig = 0;
337: return error;
338: }
339:
340: char *HostCore::sendsig(long sig)
341: {
342: if( !online() ) return "send signal: process not live";
343: if( ::ioctl(corefd, PIOCKILL, &sig) >= 0 )
344: return 0;
345: return SysErr( "send signal (PIOCKILL): " );
346: }
347:
348: Context* HostCore::newContext()
349: {
350: HostContext *cc = new HostContext;
351: cc->error = 0;
352: cc->core = this;
353: cc->pending = 0;
354: if( pr.p_stat != SSTOP )
355: cc->error = "context save: process not stopped";
356: else if( peek(pc()-2)->sht == M68K_TRAP0 )
357: cc->error = "context save: process in system call";
358: else if( cc->pending = pr.p_cursig )
359: cc->error = clrcurrsig();
360: if( !cc->error )
361: for( int i = 0; i < 18; ++i )
362: cc->regs[i] = regpeek(i);
363: return cc;
364: }
365:
366: void HostContext::restore() // should use only PIOCSSIG eventually
367: {
368: if( pending ){
369: if( ::ioctl(core->corefd, PIOCSSIG, &pending) == 0 )
370: core->pr.p_cursig = pending;
371: else {
372: static once = 0;
373: if( once++ == 0 )
374: PadsWarn("warning: unix out of date?: PIOCSSIG");
375: if( error = core->sendsig(pending) )
376: return;
377: if( pending == SIGTRAP ){
378: if( error = core->run() ) return;
379: if( error = core->waitstop() ) return;
380: error = core->readcontrol();
381: } else
382: error = core->step(); // other signals
383: if( error )
384: return;
385: }
386: }
387: for( int i = 0; i < 18; ++i )
388: if( error = core->regpoke(i, regs[i]) )
389: return;
390: }
391:
392: void WaitForExecHang(char *procpath)
393: {
394: int fd = open(procpath, 0);
395: for( int i = 1; i <= 15; ++i ){
396: proc p;
397: if( ::ioctl(fd, PIOCGETPR, &p) >= 0 ){
398: if( p.p_stat == SSTOP ){
399: close(fd);
400: return;
401: }
402: }
403: sleep(1);
404: }
405: close(fd);
406: }
407:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.