plan9port

[fork] Plan 9 from user space
git clone git://src.adamsgaard.dk/plan9port # fast
git clone https://src.adamsgaard.dk/plan9port.git # slow
Log | Files | Refs | README | LICENSE Back to index

port (10931B)


      1 // portable acid for all architectures
      2 
      3 defn pfl(addr)
      4 {
      5 	print(pcfile(addr), ":", pcline(addr), "\n");
      6 }
      7 
      8 defn
      9 notestk(addr)
     10 {
     11 	local pc, sp;
     12 	complex Ureg addr;
     13 
     14 	pc = addr.pc\X;
     15 	sp = addr.sp\X;
     16 
     17 	print("Note pc:", pc, " sp:", sp, " ", fmt(pc, 'a'), " ");
     18 	pfl(pc);
     19 	_stk({"PC", pc, "SP", sp, linkreg(addr)}, 1);
     20 }
     21 
     22 defn
     23 notelstk(addr)
     24 {
     25 	local pc, sp;
     26 	complex Ureg addr;
     27 
     28 	pc = addr.pc\X;
     29 	sp = addr.sp\X;
     30 
     31 	print("Note pc:", pc, " sp:", sp, " ", fmt(pc, 'a'), " ");
     32 	pfl(pc);
     33 	_stk({"PC", pc, "SP", sp, linkreg(addr)}, 1);
     34 }
     35 
     36 defn params(param)
     37 {
     38 	while param do {
     39 		sym = head param;
     40 		print(sym[0], "=", itoa(sym[1], "%#ux"));
     41 		param = tail param;
     42 		if param then
     43 			print (",");
     44 	}	
     45 }
     46 
     47 stkprefix = "";
     48 stkignore = {};
     49 stkend = 0;
     50 
     51 defn locals(l)
     52 {
     53 	local sym;
     54 
     55 	while l do {
     56 		sym = head l;
     57 		print(stkprefix, "\t", sym[0], "=", itoa(sym[1], "%#ux"), "\n");
     58 		l = tail l;
     59 	}	
     60 }
     61 
     62 defn _stkign(frame)
     63 {
     64 	local file;
     65 
     66 	file = pcfile(frame[0]);
     67 	s = stkignore;
     68 	while s do {
     69 		if regexp(head s, file) then
     70 			return 1;
     71 		s = tail s;
     72 	}
     73 	return 0;
     74 }
     75 
     76 // print a stack trace
     77 //
     78 // in a run of leading frames in files matched by regexps in stkignore,
     79 // only print the last one.
     80 defn _stk(regs, dolocals)
     81 {
     82 	local stk, frame, pc, fn, done, callerpc, paramlist, locallist;
     83 
     84 	stk = strace(regs);
     85 	if stkignore then {
     86 		while stk && tail stk && _stkign(head tail stk) do
     87 			stk = tail stk;
     88 	}
     89 
     90 	callerpc = 0;
     91 	done = 0;
     92 	while stk && !done do {
     93 		frame = head stk;
     94 		stk = tail stk;
     95 		fn = frame[0];
     96 		pc = frame[1];
     97 		callerpc = frame[2];
     98 		paramlist = frame[3];
     99 		locallist = frame[4];
    100 
    101 		print(stkprefix, fmt(fn, 'a'), "(");
    102 		params(paramlist);
    103 		print(")");
    104 		if pc != fn then
    105 			print("+", itoa(pc-fn, "%#ux"));
    106 		print(" ");
    107 		pfl(pc);
    108 		if dolocals then
    109 			locals(locallist);
    110 		if fn == var("threadmain") || fn == var("p9main") then
    111 			done=1;
    112 		if fn == var("threadstart") || fn == var("scheduler") then
    113 			done=1;
    114 		if callerpc == 0 then
    115 			done=1;
    116 	}
    117 	if callerpc && !done then {
    118 		print(stkprefix, fmt(callerpc, 'a'), " ");
    119 		pfl(callerpc);
    120 	}
    121 }
    122 
    123 defn findsrc(file)
    124 {
    125 	local lst, src;
    126 
    127 	if file[0] == '/' then {
    128 		src = file(file);
    129 		if src != {} then {
    130 			srcfiles = append srcfiles, file;
    131 			srctext = append srctext, src;
    132 			return src;
    133 		}
    134 		return {};
    135 	}
    136 
    137 	lst = srcpath;
    138 	while head lst do {
    139 		src = file(head lst+file);
    140 		if src != {} then {
    141 			srcfiles = append srcfiles, file;
    142 			srctext = append srctext, src;
    143 			return src;
    144 		}
    145 		lst = tail lst;
    146 	}
    147 }
    148 
    149 defn line(addr)
    150 {
    151 	local src, file;
    152 
    153 	file = pcfile(addr);
    154 	src = match(file, srcfiles);
    155 
    156 	if src >= 0 then
    157 		src = srctext[src];
    158 	else
    159 		src = findsrc(file);
    160 
    161 	if src == {} then {
    162 		print("no source for ", file, "\n");
    163 		return {};
    164 	}
    165 	line = pcline(addr)-1;
    166 	print(file, ":", src[line], "\n");
    167 }
    168 
    169 defn addsrcdir(dir)
    170 {
    171 	dir = dir+"/";
    172 
    173 	if match(dir, srcpath) >= 0 then {
    174 		print("already in srcpath\n");
    175 		return {};
    176 	}
    177 
    178 	srcpath = {dir}+srcpath;
    179 }
    180 
    181 defn source()
    182 {
    183 	local l;
    184 
    185 	l = srcpath;
    186 	while l do {
    187 		print(head l, "\n");
    188 		l = tail l;
    189 	}
    190 	l = srcfiles;
    191 
    192 	while l do {
    193 		print("\t", head l, "\n");
    194 		l = tail l;
    195 	}
    196 }
    197 
    198 defn Bsrc(addr)
    199 {
    200 	local lst;
    201 
    202 	lst = srcpath;
    203 	file = pcfile(addr);
    204 	if file[0] == '/' && access(file) then {
    205 		rc("B "+file+":"+itoa(pcline(addr)));
    206 		return {};
    207 	}
    208 	while head lst do {
    209 		name = head lst+file;
    210 		if access(name) then {
    211 			rc("B "+name+":"+itoa(pcline(addr)));
    212 			return {};
    213 		}
    214 		lst = tail lst;
    215 	}
    216 	print("no source for ", file, "\n");
    217 }
    218 
    219 defn srcline(addr)
    220 {
    221 	local text, cline, line, file, src;
    222 	file = pcfile(addr);
    223 	src = match(file,srcfiles);
    224 	if (src>=0) then
    225 		src = srctext[src];
    226 	else
    227 		src = findsrc(file);
    228 	if (src=={}) then
    229 	{
    230 		return "(no source)";
    231 	}
    232 	return src[pcline(addr)-1];
    233 }
    234 
    235 defn src(addr)
    236 {
    237 	local src, file, line, cline, text;
    238 
    239 	file = pcfile(addr);
    240 	src = match(file, srcfiles);
    241 
    242 	if src >= 0 then
    243 		src = srctext[src];
    244 	else
    245 		src = findsrc(file);
    246 
    247 	if src == {} then {
    248 		print("no source for ", file, "\n");
    249 		return {};
    250 	}
    251 
    252 	cline = pcline(addr)-1;
    253 	print(file, ":", cline+1, "\n");
    254 	line = cline-5;
    255 	loop 0,10 do {
    256 		if line >= 0 then {
    257 			if line == cline then
    258 				print(">");
    259 			else
    260 				print(" ");
    261 			text = src[line];
    262 			if text == {} then
    263 				return {};
    264 			print(line+1, "\t", text, "\n");
    265 		}
    266 		line = line+1;
    267 	}	
    268 }
    269 
    270 defn step()					// single step the process
    271 {
    272 	local lst, lpl, addr, bput;
    273 
    274 	bput = 0;
    275 	if match(*PC, bplist) >= 0 then {	// Sitting on a breakpoint
    276 		bput = fmt(*PC, bpfmt);
    277 		*bput = @bput;
    278 	}
    279 
    280 	lst = follow(*PC);
    281 
    282 	lpl = lst;
    283 	while lpl do {				// place break points
    284 		*(head lpl) = bpinst;
    285 		lpl = tail lpl;
    286 	}
    287 
    288 	startstop(pid);				// do the step
    289 
    290 	while lst do {				// remove the breakpoints
    291 		addr = fmt(head lst, bpfmt);
    292 		*addr = @addr;
    293 		lst = tail lst;
    294 	}
    295 	if bput != 0 then
    296 		*bput = bpinst;
    297 }
    298 
    299 defn bpset(addr)				// set a breakpoint
    300 {
    301 	if status(pid) != "Stopped" then {
    302 		print("Waiting...\n");
    303 		stop(pid);
    304 	}
    305 	if match(addr, bplist) >= 0 then
    306 		print("breakpoint already set at ", fmt(addr, 'a'), "\n");
    307 	else {
    308 		*fmt(addr, bpfmt) = bpinst;
    309 		bplist = append bplist, addr;
    310 	}
    311 }
    312 
    313 defn bptab()					// print a table of breakpoints
    314 {
    315 	local lst, addr;
    316 
    317 	lst = bplist;
    318 	while lst do {
    319 		addr = head lst;
    320 		print("\t", fmt(addr, 'X'), " ", fmt(addr, 'a'), "  ", fmt(addr, 'i'), "\n");
    321 		lst = tail lst;
    322 	}
    323 }
    324 
    325 defn bpdel(addr)				// delete a breakpoint
    326 {
    327 	local n, pc, nbplist;
    328 
    329 	if addr == 0 then {
    330 		while bplist do {
    331 			pc = head bplist;
    332 			pc = fmt(pc, bpfmt);
    333 			*pc = @pc;
    334 			bplist = tail bplist;
    335 		}
    336 		return {};
    337 	}
    338 
    339 	n = match(addr, bplist);
    340 	if n < 0  then {
    341 		print("no breakpoint at ", fmt(addr, 'a'), "\n");
    342 		return {};
    343 	}
    344 
    345 	addr = fmt(addr, bpfmt);
    346 	*addr = @addr;
    347 
    348 	nbplist = {};				// delete from list
    349 	while bplist do {
    350 		pc = head bplist;
    351 		if pc != addr then
    352 			nbplist = append nbplist, pc;
    353 		bplist = tail bplist;
    354 	}
    355 	bplist = nbplist;			// delete from memory
    356 }
    357 
    358 defn cont()					// continue execution
    359 {
    360 	local addr;
    361 
    362 	addr = fmt(*PC, bpfmt);
    363 	if match(addr, bplist) >= 0 then {	// Sitting on a breakpoint
    364 		*addr = @addr;
    365 		step();				// Step over
    366 		*addr = bpinst;
    367 	}
    368 	startstop(pid);				// Run
    369 }
    370 
    371 defn stopped(pid)		// called from acid when a process changes state
    372 {
    373 	pfixstop(pid);
    374 	pstop(pid);		// stub so this is easy to replace
    375 }
    376 
    377 defn procs()			// print status of processes
    378 {
    379 	local c, lst, cpid;
    380 
    381 	cpid = pid;
    382 	lst = proclist;
    383 	while lst do {
    384 		np = head lst;
    385 		setproc(np);
    386 		if np == cpid then
    387 			c = '>';
    388 		else
    389 			c = ' ';
    390 		print(fmt(c, 'c'), np, ": ", status(np), " at ", fmt(*PC, 'a'), " setproc(", np, ")\n");
    391 		lst = tail lst;
    392 	}
    393 	pid = cpid;
    394 	if pid != 0 then
    395 		setproc(pid);
    396 }
    397 
    398 _asmlines = 30;
    399 
    400 defn asm(addr)
    401 {
    402 	local bound;
    403 
    404 	bound = fnbound(addr);
    405 
    406 	addr = fmt(addr, 'i');
    407 	loop 1,_asmlines do {
    408 		print(fmt(addr, 'a'), " ", fmt(addr, 'X'));
    409 		print("\t", @addr++, "\n");
    410 		if bound != {} && addr > bound[1] then {
    411 			lasmaddr = addr;
    412 			return {};
    413 		}
    414 	}
    415 	lasmaddr = addr;
    416 }
    417 
    418 defn casm()
    419 {
    420 	asm(lasmaddr);
    421 }
    422 
    423 defn xasm(addr)
    424 {
    425 	local bound;
    426 
    427 	bound = fnbound(addr);
    428 
    429 	addr = fmt(addr, 'i');
    430 	loop 1,_asmlines do {
    431 		print(fmt(addr, 'a'), " ", fmt(addr, 'X'));
    432 		print("\t", *addr++, "\n");
    433 		if bound != {} && addr > bound[1] then {
    434 			lasmaddr = addr;
    435 			return {};
    436 		}
    437 	}
    438 	lasmaddr = addr;
    439 }
    440 
    441 defn xcasm()
    442 {
    443 	xasm(lasmaddr);
    444 }
    445 
    446 defn win()
    447 {
    448 	local npid, estr;
    449 
    450 	bplist = {};
    451 	notes = {};
    452 
    453 	estr = "/sys/lib/acid/window '0 0 600 400' "+textfile;
    454 	if progargs != "" then
    455 		estr = estr+" "+progargs;
    456 
    457 	npid = rc(estr);
    458 	npid = atoi(npid);
    459 	if npid == 0 then
    460 		error("win failed to create process");
    461 
    462 	setproc(npid);
    463 	stopped(npid);
    464 }
    465 
    466 defn win2()
    467 {
    468 	local npid, estr;
    469 
    470 	bplist = {};
    471 	notes = {};
    472 
    473 	estr = "/sys/lib/acid/transcript '0 0 600 400' '100 100 700 500' "+textfile;
    474 	if progargs != "" then
    475 		estr = estr+" "+progargs;
    476 
    477 	npid = rc(estr);
    478 	npid = atoi(npid);
    479 	if npid == 0 then
    480 		error("win failed to create process");
    481 
    482 	setproc(npid);
    483 	stopped(npid);
    484 }
    485 
    486 printstopped = 1;
    487 defn new()
    488 {
    489 	local a;
    490 	
    491 	bplist = {};
    492 	newproc(progargs);
    493 	a = var("p9main");
    494 	if a == {} then
    495 		a = var("main");
    496 	if a == {} then
    497 		return {};
    498 	bpset(a);
    499 	while *PC != a do
    500 		cont();
    501 	bpdel(a);
    502 }
    503 
    504 defn stmnt()			// step one statement
    505 {
    506 	local line;
    507 
    508 	line = pcline(*PC);
    509 	while 1 do {
    510 		step();
    511 		if line != pcline(*PC) then {
    512 			src(*PC);
    513 			return {};
    514 		}
    515 	}
    516 }
    517 
    518 defn func()			// step until we leave the current function
    519 {
    520 	local bound, end, start, pc;
    521 
    522 	bound = fnbound(*PC);
    523 	if bound == {} then {
    524 		print("cannot locate text symbol\n");
    525 		return {};
    526 	}
    527 
    528 	pc = *PC;
    529 	start = bound[0];
    530 	end = bound[1];
    531 	while pc >= start && pc < end do {
    532 		step();
    533 		pc = *PC;
    534 	}
    535 }
    536 
    537 defn next()
    538 {
    539 	local sp, bound, pc;
    540 
    541 	sp = *SP;
    542 	bound = fnbound(*PC);
    543 	if bound == {} then {
    544 		print("cannot locate text symbol\n");
    545 		return {};
    546 	}
    547 	stmnt();
    548 	pc = *PC;
    549 	if pc >= bound[0] && pc < bound[1] then
    550 		return {};
    551 
    552 	while (pc < bound[0] || pc > bound[1]) && sp >= *SP do {
    553 		step();
    554 		pc = *PC;
    555 	}
    556 	src(*PC);
    557 }
    558 
    559 defn maps()
    560 {
    561 	local m, mm;
    562 
    563 	m = map();
    564 	while m != {} do {
    565 		mm = head m;
    566 		m = tail m;
    567 		print(mm[2]\X, " ", mm[3]\X, " ", mm[4]\X, " ", mm[0], " ", mm[1], "\n");
    568 	}
    569 }
    570 
    571 defn dump(addr, n, fmt)
    572 {
    573 	loop 0, n do {
    574 		print(fmt(addr, 'X'), ": ");
    575 		addr = mem(addr, fmt);
    576 	}
    577 }
    578 
    579 defn mem(addr, fmt)
    580 {
    581 
    582 	local i, c, n;
    583 
    584 	i = 0;
    585 	while fmt[i] != 0 do {
    586 		c = fmt[i];
    587 		n = 0;
    588 		while '0' <= fmt[i] && fmt[i] <= '9' do {
    589 			n = 10*n + fmt[i]-'0';
    590 			i = i+1;
    591 		}
    592 		if n <= 0 then n = 1;
    593 		addr = fmt(addr, fmt[i]);
    594 		while n > 0 do {
    595 			print(*addr++, " ");
    596 			n = n-1;
    597 		}
    598 		i = i+1;
    599 	}
    600 	print("\n");
    601 	return addr;
    602 }
    603 
    604 defn symbols(pattern)
    605 {
    606 	local l, s, name;
    607 	
    608 	l = symbols;
    609 	while l do {
    610 		s = head l;
    611 		if regexp(pattern, s[0]) then {
    612 			name = s[4];
    613 			if name == {} then
    614 				name = "";
    615 			print(s[0], "\t", s[1], "\t", s[2], "\t", s[3], "\t", name, "\n");
    616 		}
    617 		l = tail l;
    618 	}
    619 }
    620 
    621 defn havesymbol(name)
    622 {
    623 	local l, s;
    624 
    625 	l = symbols;
    626 	while l do {
    627 		s = head l;
    628 		l = tail l;
    629 		if s[0] == name then
    630 			return 1;
    631 	}
    632 	return 0;
    633 }
    634 
    635 defn spsrch(len)
    636 {
    637 	local addr, a, s, e;
    638 
    639 	addr = *SP;
    640 	s = origin & 0x7fffffff;
    641 	e = etext & 0x7fffffff;
    642 	loop 1, len do {
    643 		a = *addr++;
    644 		c = a & 0x7fffffff;
    645 		if c > s && c < e then {
    646 			print("src(", a, ")\n");
    647 			pfl(a);
    648 		}			
    649 	}
    650 }
    651 
    652 defn acidtypes()
    653 {
    654 	local syms;
    655 	local l;
    656 
    657 	l = textfile();
    658 	if l != {} then {
    659 		syms = "acidtypes";
    660 		while l != {} do {
    661 			syms = syms + " " + ((head l)[0]);
    662 			l = tail l;
    663 		}
    664 		includepipe(syms);
    665 	}
    666 }
    667 
    668 defn getregs()
    669 {
    670 	local regs, l;
    671 
    672 	regs = {};
    673 	l = registers;
    674 	while l != {} do {
    675 		regs = append regs, var(l[0]);
    676 		l = tail l;
    677 	}
    678 	return regs;
    679 }
    680 
    681 defn setregs(regs)
    682 {
    683 	local l;
    684 
    685 	l = registers;
    686 	while l != {} do {
    687 		var(l[0]) = regs[0];
    688 		l = tail l;
    689 		regs = tail regs;
    690 	}
    691 	return regs;
    692 }
    693 
    694 defn resetregs()
    695 {
    696 	local l;
    697 
    698 	l = registers;
    699 	while l != {} do {
    700 		var(l[0]) = register(l[0]);
    701 		l = tail l;
    702 	}
    703 }
    704 
    705 defn clearregs()
    706 {
    707 	local l;
    708 
    709 	l = registers;
    710 	while l != {} do {
    711 		var(l[0]) = refconst(~0);
    712 		l = tail l;
    713 	}
    714 }
    715 
    716 progargs="";
    717 print(acidfile);
    718