diff options
Diffstat (limited to 'web/l19.txt')
-rw-r--r-- | web/l19.txt | 1412 |
1 files changed, 0 insertions, 1412 deletions
diff --git a/web/l19.txt b/web/l19.txt deleted file mode 100644 index af9d0bb..0000000 --- a/web/l19.txt +++ /dev/null @@ -1,1412 +0,0 @@ --- front -6.828 Shells Lecture - -Hello. - --- intro -Bourne shell - -Simplest shell: run cmd arg arg ... - fork - exec in child - wait in parent - -More functionality: - file redirection: cmd >file - open file as fd 1 in child before exec - -Still more functionality: - pipes: cmd | cmd | cmd ... - create pipe, - run first cmd with pipe on fd 1, - run second cmd with other end of pipe on fd 0 - -More Bourne arcana: - $* - command args - "$@" - unexpanded command args - environment variables - macro substitution - if, while, for - || - && - "foo $x" - 'foo $x' - `cat foo` - --- rc -Rc Shell - - -No reparsing of input (except explicit eval). - -Variables as explicit lists. - -Explicit concatenation. - -Multiple input pipes <{cmd} - pass /dev/fd/4 as file name. - -Syntax more like C, less like Algol. - -diff <{echo hi} <{echo bye} - --- es -Es shell - - -rc++ - -Goal is to override functionality cleanly. - -Rewrite input like cmd | cmd2 as %pipe {cmd} {cmd2}. - -Users can redefine %pipe, etc. - -Need lexical scoping and let to allow new %pipe refer to old %pipe. - -Need garbage collection to collect unreachable code. - -Design principle: - minimal functionality + good defaults - allow users to customize implementations - - emacs, exokernel - --- apps -Applications - -Shell scripts are only as good as the programs they use. - (What good are pipes without cat, grep, sort, wc, etc.?) - -The more the scripts can access, the more powerful they become. - --- acme -Acme, Plan 9 text editor - -Make window system control files available to -everything, including shell. - -Can write shell scripts to script interactions. - -/home/rsc/bin/Slide -/home/rsc/bin/Slide- -/home/rsc/bin/Slide+ - -/usr/local/plan9/bin/adict - -win - --- javascript -JavaScript - -Very powerful - - not because it's a great language - - because it has a great data set - - Google Maps - - Gmail - - Ymail - - etc. - --- greasemonkey -GreaseMonkey - -// ==UserScript== -// @name Google Ring -// @namespace http://swtch.com/greasemonkey/ -// @description Changes Google Logo -// @include http://*.google.*/* -// ==/UserScript== - -(function() { - for(var i=0; i<document.images.length; i++){ - if(document.images[i].src == "http://www.google.com/intl/en/images/logo.gif") - document.images[i].src = "http://swtch.com/googlering.png"; - } -})(); - --- webscript0 -Webscript - -Why can't I script my web interactions? - -/home/rsc/plan9/bin/rc/fedex - -webscript /home/rsc/src/webscript/a3 - /home/rsc/src/webscript/a2 - --- acid -Acid, a programmable (scriptable) debugger - -defn stopped(pid) -{ - pfixstop(pid); - pstop(pid); -} - -defn pfixstop(pid) -{ - if *fmt(*PC-1, 'b') == 0xCC then { - // Linux stops us after the breakpoint, not at it - *PC = *PC-1; - } -} - -/usr/local/plan9/acid/port:/^defn.bpset -/usr/local/plan9/acid/port:/^defn.step - -defn checkpdb(pdb) -{ - loop 1,768 do { - if *pdb != 0 then { print(pdb\X, " ", *pdb\X, "\n"); } - pdb = pdb +4; - } -} - --- guis -GUIs - -Can we script guis? Not as clear. - -Acme examples show one way: - turn events into file (pipe) to read. - -Tcl/tk is close too. - -Eventually everyone turns to C. - --- others -Honorable Mentions - -Scheme - -Lisp - -AutoCAD - -Viaweb RTML - --- c -"Real" programming languages vs. Scripts - -Why does everyone eventually rewrite scripts in C? - (aka C++, C#, any compiled language) - -What do you need C for now? - -How could you make it accessible to a script language? - --- /home/rsc/bin/Slide -#!/usr/local/plan9/bin/rc - -echo name `{pwd}^/$1 | 9p write acme/$winid/ctl -echo clean | 9p write acme/$winid/ctl -echo get | 9p write acme/$winid/ctl - --- /home/rsc/bin/Slide- -#!/usr/local/plan9/bin/rc - -name=$% -current=`{basename $name} -currentx=`{9 grep -n '^'$current'([ ]|$)' index | sed 's/:.*//'} - -pagex=`{echo $currentx - 1 | hoc} -if(~ $pagex 0){ - echo no such page - exit 0 -} -page=`{sed -n $pagex^p index | awk '{print $1}'} -if(~ $#page 0){ - echo no such page - exit 0 -} - -Slide $page --- /home/rsc/bin/Slide+ -#!/usr/local/plan9/bin/rc - -name=$% -current=`{basename $name} -currentx=`{9 grep -n '^'$current'([ ]|$)' index | sed 's/:.*//'} - -pagex=`{echo $currentx + 1 | hoc} -page=`{sed -n $pagex^p index | awk '{print $1}'} -if(~ $#page 0){ - echo no such page - exit 0 -} - -Slide $page --- /usr/local/plan9/bin/adict -#!/usr/local/plan9/bin/rc - -. 9.rc -. $PLAN9/lib/acme.rc - -fn event { - # $1 - c1 origin of event - # $2 - c2 type of action - # $3 - q0 beginning of selection - # $4 - q1 end of selection - # $5 - eq0 beginning of expanded selection - # $6 - eq1 end of expanded selection - # $7 - flag - # $8 - nr number of runes in $7 - # $9 - text - # $10 - chorded argument - # $11 - origin of chorded argument - - switch($1$2){ - case E* # write to body or tag - case F* # generated by ourselves; ignore - case K* # type away we do not care - case Mi # mouse: text inserted in tag - case MI # mouse: text inserted in body - case Md # mouse: text deleted from tag - case MD # mouse: text deleted from body - - case Mx MX # button 2 in tag or body - winwriteevent $* - - case Ml ML # button 3 in tag or body - { - if(~ $dict NONE) - dictwin /adict/$9/ $9 - if not - dictwin /adict/$dict/$9 $dict $9 - } & - } -} - -fn dictwin { - newwindow - winname $1 - switch($#*){ - case 1 - dict -d '?' >[2=1] | sed 1d | winwrite body - case 2 - dict=$2 - case 3 - dict=$2 - dict -d $dict $3 >[2=1] | winwrite body - } - winctl clean - wineventloop -} - -dict=NONE -if(~ $1 -d){ - shift - dict=$2 - shift -} -if(~ $1 -d*){ - dict=`{echo $1 | sed 's/-d//'} - shift -} -if(~ $1 -*){ - echo 'usage: adict [-d dict] [word...]' >[1=2] - exit usage -} - -switch($#*){ -case 0 - if(~ $dict NONE) - dictwin /adict/ - if not - dictwin /adict/$dict/ $dict -case * - if(~ $dict NONE){ - dict=`{dict -d'?' | 9 sed -n 's/^ ([^\[ ]+).*/\1/p' | sed 1q} - if(~ $#dict 0){ - echo 'no dictionaries present on this system' >[1=2] - exit nodict - } - } - for(i) - dictwin /adict/$dict/$i $dict $i -} - --- /usr/local/plan9/lib/acme.rc -fn newwindow { - winctl=`{9p read acme/new/ctl} - winid=$winctl(1) - winctl noscroll -} - -fn winctl { - echo $* | 9p write acme/acme/$winid/ctl -} - -fn winread { - 9p read acme/acme/$winid/$1 -} - -fn winwrite { - 9p write acme/acme/$winid/$1 -} - -fn windump { - if(! ~ $1 - '') - winctl dumpdir $1 - if(! ~ $2 - '') - winctl dump $2 -} - -fn winname { - winctl name $1 -} - -fn winwriteevent { - echo $1$2$3 $4 | winwrite event -} - -fn windel { - if(~ $1 sure) - winctl delete - if not - winctl del -} - -fn wineventloop { - . <{winread event >[2]/dev/null | acmeevent} -} --- /home/rsc/plan9/rc/bin/fedex -#!/bin/rc - -if(! ~ $#* 1) { - echo usage: fedex 123456789012 >[1=2] - exit usage -} - -rfork e - -fn bgrep{ -pattern=`{echo $1 | sed 's;/;\\&;'} -shift - -@{ echo 'X { -$ -a - -. -} -X ,x/(.+\n)+\n/ g/'$pattern'/p' | -sam -d $* >[2]/dev/null -} -} - -fn awk2 { - awk 'NR%2==1 { a=$0; } - NR%2==0 { b=$0; printf("%-30s %s\n", a, b); } - ' $* -} - -fn awk3 { - awk '{line[NR] = $0} - END{ - i = 4; - while(i < NR){ - what=line[i++]; - when=line[i]; - comment=""; - if(!(when ~ /..\/..\/.... ..:../)){ - # out of sync - printf("%s\n", what); - continue; - } - i++; - if(!(line[i+1] ~ /..\/..\/.... ..:../) && - (i+2 > NR || line[i+2] ~ /..\/..\/.... ..:../)){ - what = what ", " line[i++]; - } - printf("%s %s\n", when, what); - } - }' $* -} - -# hget 'http://www.fedex.com/cgi-bin/track_it?airbill_list='$1'&kurrent_airbill='$1'&language=english&cntry_code=us&state=0' | -hget 'http://www.fedex.com/cgi-bin/tracking?action=track&language=english&cntry_code=us&initial=x&mps=y&tracknumbers='$1 | - htmlfmt >/tmp/fedex.$pid -sed -n '/Tracking number/,/^$/p' /tmp/fedex.$pid | awk2 -echo -sed -n '/Reference number/,/^$/p' /tmp/fedex.$pid | awk2 -echo -sed -n '/Date.time/,/^$/p' /tmp/fedex.$pid | sed 1,4d | fmt -l 4000 | sed 's/ [A-Z][A-Z] /&\n/g' -rm /tmp/fedex.$pid --- /home/rsc/src/webscript/a3 -#!./o.webscript - -load "http://www.ups.com/WebTracking/track?loc=en_US" -find textbox "InquiryNumber1" -input "1z30557w0340175623" -find next checkbox -input "yes" -find prev form -submit -if(find "Delivery Information"){ - find outer table - print -}else if(find "One or more"){ - print -}else{ - print "Unexpected results." - find page - print -} --- /home/rsc/src/webscript/a2 -#load "http://apc-reset/outlets.htm" -load "apc.html" -print -print "\n=============\n" -find "yoshimi" -find outer row -find next select -input "Immediate Reboot" -submit -print --- /usr/local/plan9/acid/port -// portable acid for all architectures - -defn pfl(addr) -{ - print(pcfile(addr), ":", pcline(addr), "\n"); -} - -defn -notestk(addr) -{ - local pc, sp; - complex Ureg addr; - - pc = addr.pc\X; - sp = addr.sp\X; - - print("Note pc:", pc, " sp:", sp, " ", fmt(pc, 'a'), " "); - pfl(pc); - _stk({"PC", pc, "SP", sp, linkreg(addr)}, 1); -} - -defn -notelstk(addr) -{ - local pc, sp; - complex Ureg addr; - - pc = addr.pc\X; - sp = addr.sp\X; - - print("Note pc:", pc, " sp:", sp, " ", fmt(pc, 'a'), " "); - pfl(pc); - _stk({"PC", pc, "SP", sp, linkreg(addr)}, 1); -} - -defn params(param) -{ - while param do { - sym = head param; - print(sym[0], "=", itoa(sym[1], "%#ux")); - param = tail param; - if param then - print (","); - } -} - -stkprefix = ""; -stkignore = {}; -stkend = 0; - -defn locals(l) -{ - local sym; - - while l do { - sym = head l; - print(stkprefix, "\t", sym[0], "=", itoa(sym[1], "%#ux"), "\n"); - l = tail l; - } -} - -defn _stkign(frame) -{ - local file; - - file = pcfile(frame[0]); - s = stkignore; - while s do { - if regexp(head s, file) then - return 1; - s = tail s; - } - return 0; -} - -// print a stack trace -// -// in a run of leading frames in files matched by regexps in stkignore, -// only print the last one. -defn _stk(regs, dolocals) -{ - local stk, frame, pc, fn, done, callerpc, paramlist, locallist; - - stk = strace(regs); - if stkignore then { - while stk && tail stk && _stkign(head tail stk) do - stk = tail stk; - } - - callerpc = 0; - done = 0; - while stk && !done do { - frame = head stk; - stk = tail stk; - fn = frame[0]; - pc = frame[1]; - callerpc = frame[2]; - paramlist = frame[3]; - locallist = frame[4]; - - print(stkprefix, fmt(fn, 'a'), "("); - params(paramlist); - print(")"); - if pc != fn then - print("+", itoa(pc-fn, "%#ux")); - print(" "); - pfl(pc); - if dolocals then - locals(locallist); - if fn == var("threadmain") || fn == var("p9main") then - done=1; - if fn == var("threadstart") || fn == var("scheduler") then - done=1; - if callerpc == 0 then - done=1; - } - if callerpc && !done then { - print(stkprefix, fmt(callerpc, 'a'), " "); - pfl(callerpc); - } -} - -defn findsrc(file) -{ - local lst, src; - - if file[0] == '/' then { - src = file(file); - if src != {} then { - srcfiles = append srcfiles, file; - srctext = append srctext, src; - return src; - } - return {}; - } - - lst = srcpath; - while head lst do { - src = file(head lst+file); - if src != {} then { - srcfiles = append srcfiles, file; - srctext = append srctext, src; - return src; - } - lst = tail lst; - } -} - -defn line(addr) -{ - local src, file; - - file = pcfile(addr); - src = match(file, srcfiles); - - if src >= 0 then - src = srctext[src]; - else - src = findsrc(file); - - if src == {} then { - print("no source for ", file, "\n"); - return {}; - } - line = pcline(addr)-1; - print(file, ":", src[line], "\n"); -} - -defn addsrcdir(dir) -{ - dir = dir+"/"; - - if match(dir, srcpath) >= 0 then { - print("already in srcpath\n"); - return {}; - } - - srcpath = {dir}+srcpath; -} - -defn source() -{ - local l; - - l = srcpath; - while l do { - print(head l, "\n"); - l = tail l; - } - l = srcfiles; - - while l do { - print("\t", head l, "\n"); - l = tail l; - } -} - -defn Bsrc(addr) -{ - local lst; - - lst = srcpath; - file = pcfile(addr); - if file[0] == '/' && access(file) then { - rc("B "+file+":"+itoa(pcline(addr))); - return {}; - } - while head lst do { - name = head lst+file; - if access(name) then { - rc("B "+name+":"+itoa(pcline(addr))); - return {}; - } - lst = tail lst; - } - print("no source for ", file, "\n"); -} - -defn srcline(addr) -{ - local text, cline, line, file, src; - file = pcfile(addr); - src = match(file,srcfiles); - if (src>=0) then - src = srctext[src]; - else - src = findsrc(file); - if (src=={}) then - { - return "(no source)"; - } - return src[pcline(addr)-1]; -} - -defn src(addr) -{ - local src, file, line, cline, text; - - file = pcfile(addr); - src = match(file, srcfiles); - - if src >= 0 then - src = srctext[src]; - else - src = findsrc(file); - - if src == {} then { - print("no source for ", file, "\n"); - return {}; - } - - cline = pcline(addr)-1; - print(file, ":", cline+1, "\n"); - line = cline-5; - loop 0,10 do { - if line >= 0 then { - if line == cline then - print(">"); - else - print(" "); - text = src[line]; - if text == {} then - return {}; - print(line+1, "\t", text, "\n"); - } - line = line+1; - } -} - -defn step() // single step the process -{ - local lst, lpl, addr, bput; - - bput = 0; - if match(*PC, bplist) >= 0 then { // Sitting on a breakpoint - bput = fmt(*PC, bpfmt); - *bput = @bput; - } - - lst = follow(*PC); - - lpl = lst; - while lpl do { // place break points - *(head lpl) = bpinst; - lpl = tail lpl; - } - - startstop(pid); // do the step - - while lst do { // remove the breakpoints - addr = fmt(head lst, bpfmt); - *addr = @addr; - lst = tail lst; - } - if bput != 0 then - *bput = bpinst; -} - -defn bpset(addr) // set a breakpoint -{ - if status(pid) != "Stopped" then { - print("Waiting...\n"); - stop(pid); - } - if match(addr, bplist) >= 0 then - print("breakpoint already set at ", fmt(addr, 'a'), "\n"); - else { - *fmt(addr, bpfmt) = bpinst; - bplist = append bplist, addr; - } -} - -defn bptab() // print a table of breakpoints -{ - local lst, addr; - - lst = bplist; - while lst do { - addr = head lst; - print("\t", fmt(addr, 'X'), " ", fmt(addr, 'a'), " ", fmt(addr, 'i'), "\n"); - lst = tail lst; - } -} - -defn bpdel(addr) // delete a breakpoint -{ - local n, pc, nbplist; - - if addr == 0 then { - while bplist do { - pc = head bplist; - pc = fmt(pc, bpfmt); - *pc = @pc; - bplist = tail bplist; - } - return {}; - } - - n = match(addr, bplist); - if n < 0 then { - print("no breakpoint at ", fmt(addr, 'a'), "\n"); - return {}; - } - - addr = fmt(addr, bpfmt); - *addr = @addr; - - nbplist = {}; // delete from list - while bplist do { - pc = head bplist; - if pc != addr then - nbplist = append nbplist, pc; - bplist = tail bplist; - } - bplist = nbplist; // delete from memory -} - -defn cont() // continue execution -{ - local addr; - - addr = fmt(*PC, bpfmt); - if match(addr, bplist) >= 0 then { // Sitting on a breakpoint - *addr = @addr; - step(); // Step over - *addr = bpinst; - } - startstop(pid); // Run -} - -defn stopped(pid) // called from acid when a process changes state -{ - pfixstop(pid); - pstop(pid); // stub so this is easy to replace -} - -defn procs() // print status of processes -{ - local c, lst, cpid; - - cpid = pid; - lst = proclist; - while lst do { - np = head lst; - setproc(np); - if np == cpid then - c = '>'; - else - c = ' '; - print(fmt(c, 'c'), np, ": ", status(np), " at ", fmt(*PC, 'a'), " setproc(", np, ")\n"); - lst = tail lst; - } - pid = cpid; - if pid != 0 then - setproc(pid); -} - -_asmlines = 30; - -defn asm(addr) -{ - local bound; - - bound = fnbound(addr); - - addr = fmt(addr, 'i'); - loop 1,_asmlines do { - print(fmt(addr, 'a'), " ", fmt(addr, 'X')); - print("\t", @addr++, "\n"); - if bound != {} && addr > bound[1] then { - lasmaddr = addr; - return {}; - } - } - lasmaddr = addr; -} - -defn casm() -{ - asm(lasmaddr); -} - -defn xasm(addr) -{ - local bound; - - bound = fnbound(addr); - - addr = fmt(addr, 'i'); - loop 1,_asmlines do { - print(fmt(addr, 'a'), " ", fmt(addr, 'X')); - print("\t", *addr++, "\n"); - if bound != {} && addr > bound[1] then { - lasmaddr = addr; - return {}; - } - } - lasmaddr = addr; -} - -defn xcasm() -{ - xasm(lasmaddr); -} - -defn win() -{ - local npid, estr; - - bplist = {}; - notes = {}; - - estr = "/sys/lib/acid/window '0 0 600 400' "+textfile; - if progargs != "" then - estr = estr+" "+progargs; - - npid = rc(estr); - npid = atoi(npid); - if npid == 0 then - error("win failed to create process"); - - setproc(npid); - stopped(npid); -} - -defn win2() -{ - local npid, estr; - - bplist = {}; - notes = {}; - - estr = "/sys/lib/acid/transcript '0 0 600 400' '100 100 700 500' "+textfile; - if progargs != "" then - estr = estr+" "+progargs; - - npid = rc(estr); - npid = atoi(npid); - if npid == 0 then - error("win failed to create process"); - - setproc(npid); - stopped(npid); -} - -printstopped = 1; -defn new() -{ - local a; - - bplist = {}; - newproc(progargs); - a = var("p9main"); - if a == {} then - a = var("main"); - if a == {} then - return {}; - bpset(a); - while *PC != a do - cont(); - bpdel(a); -} - -defn stmnt() // step one statement -{ - local line; - - line = pcline(*PC); - while 1 do { - step(); - if line != pcline(*PC) then { - src(*PC); - return {}; - } - } -} - -defn func() // step until we leave the current function -{ - local bound, end, start, pc; - - bound = fnbound(*PC); - if bound == {} then { - print("cannot locate text symbol\n"); - return {}; - } - - pc = *PC; - start = bound[0]; - end = bound[1]; - while pc >= start && pc < end do { - step(); - pc = *PC; - } -} - -defn next() -{ - local sp, bound, pc; - - sp = *SP; - bound = fnbound(*PC); - if bound == {} then { - print("cannot locate text symbol\n"); - return {}; - } - stmnt(); - pc = *PC; - if pc >= bound[0] && pc < bound[1] then - return {}; - - while (pc < bound[0] || pc > bound[1]) && sp >= *SP do { - step(); - pc = *PC; - } - src(*PC); -} - -defn maps() -{ - local m, mm; - - m = map(); - while m != {} do { - mm = head m; - m = tail m; - print(mm[2]\X, " ", mm[3]\X, " ", mm[4]\X, " ", mm[0], " ", mm[1], "\n"); - } -} - -defn dump(addr, n, fmt) -{ - loop 0, n do { - print(fmt(addr, 'X'), ": "); - addr = mem(addr, fmt); - } -} - -defn mem(addr, fmt) -{ - - local i, c, n; - - i = 0; - while fmt[i] != 0 do { - c = fmt[i]; - n = 0; - while '0' <= fmt[i] && fmt[i] <= '9' do { - n = 10*n + fmt[i]-'0'; - i = i+1; - } - if n <= 0 then n = 1; - addr = fmt(addr, fmt[i]); - while n > 0 do { - print(*addr++, " "); - n = n-1; - } - i = i+1; - } - print("\n"); - return addr; -} - -defn symbols(pattern) -{ - local l, s; - - l = symbols; - while l do { - s = head l; - if regexp(pattern, s[0]) then - print(s[0], "\t", s[1], "\t", s[2], "\t", s[3], "\n"); - l = tail l; - } -} - -defn havesymbol(name) -{ - local l, s; - - l = symbols; - while l do { - s = head l; - l = tail l; - if s[0] == name then - return 1; - } - return 0; -} - -defn spsrch(len) -{ - local addr, a, s, e; - - addr = *SP; - s = origin & 0x7fffffff; - e = etext & 0x7fffffff; - loop 1, len do { - a = *addr++; - c = a & 0x7fffffff; - if c > s && c < e then { - print("src(", a, ")\n"); - pfl(a); - } - } -} - -defn acidtypes() -{ - local syms; - local l; - - l = textfile(); - if l != {} then { - syms = "acidtypes"; - while l != {} do { - syms = syms + " " + ((head l)[0]); - l = tail l; - } - includepipe(syms); - } -} - -defn getregs() -{ - local regs, l; - - regs = {}; - l = registers; - while l != {} do { - regs = append regs, var(l[0]); - l = tail l; - } - return regs; -} - -defn setregs(regs) -{ - local l; - - l = registers; - while l != {} do { - var(l[0]) = regs[0]; - l = tail l; - regs = tail regs; - } - return regs; -} - -defn resetregs() -{ - local l; - - l = registers; - while l != {} do { - var(l[0]) = register(l[0]); - l = tail l; - } -} - -defn clearregs() -{ - local l; - - l = registers; - while l != {} do { - var(l[0]) = refconst(~0); - l = tail l; - } -} - -progargs=""; -print(acidfile); - --- /usr/local/plan9/acid/386 -// 386 support - -defn acidinit() // Called after all the init modules are loaded -{ - bplist = {}; - bpfmt = 'b'; - - srcpath = { - "./", - "/sys/src/libc/port/", - "/sys/src/libc/9sys/", - "/sys/src/libc/386/" - }; - - srcfiles = {}; // list of loaded files - srctext = {}; // the text of the files -} - -defn linkreg(addr) -{ - return {}; -} - -defn stk() // trace -{ - _stk({"PC", *PC, "SP", *SP}, 0); -} - -defn lstk() // trace with locals -{ - _stk({"PC", *PC, "SP", *SP}, 1); -} - -defn gpr() // print general(hah hah!) purpose registers -{ - print("AX\t", *AX, " BX\t", *BX, " CX\t", *CX, " DX\t", *DX, "\n"); - print("DI\t", *DI, " SI\t", *SI, " BP\t", *BP, "\n"); -} - -defn spr() // print special processor registers -{ - local pc; - local cause; - - pc = *PC; - print("PC\t", pc, " ", fmt(pc, 'a'), " "); - pfl(pc); - print("SP\t", *SP, " ECODE ", *ECODE, " EFLAG ", *EFLAGS, "\n"); - print("CS\t", *CS, " DS\t ", *DS, " SS\t", *SS, "\n"); - print("GS\t", *GS, " FS\t ", *FS, " ES\t", *ES, "\n"); - - cause = *TRAP; - print("TRAP\t", cause, " ", reason(cause), "\n"); -} - -defn regs() // print all registers -{ - spr(); - gpr(); -} - -defn mmregs() -{ - print("MM0\t", *MM0, " MM1\t", *MM1, "\n"); - print("MM2\t", *MM2, " MM3\t", *MM3, "\n"); - print("MM4\t", *MM4, " MM5\t", *MM5, "\n"); - print("MM6\t", *MM6, " MM7\t", *MM7, "\n"); -} - -defn pfixstop(pid) -{ - if *fmt(*PC-1, 'b') == 0xCC then { - // Linux stops us after the breakpoint, not at it - *PC = *PC-1; - } -} - - -defn pstop(pid) -{ - local l; - local pc; - local why; - - pc = *PC; - - // FIgure out why we stopped. - if *fmt(pc, 'b') == 0xCC then { - why = "breakpoint"; - - // fix up instruction for print; will put back later - *pc = @pc; - } else if *(pc-2\x) == 0x80CD then { - pc = pc-2; - why = "system call"; - } else - why = "stopped"; - - if printstopped then { - print(pid,": ", why, "\t"); - print(fmt(pc, 'a'), "\t", *fmt(pc, 'i'), "\n"); - } - - if why == "breakpoint" then - *fmt(pc, bpfmt) = bpinst; - - if printstopped && notes then { - if notes[0] != "sys: breakpoint" then { - print("Notes pending:\n"); - l = notes; - while l do { - print("\t", head l, "\n"); - l = tail l; - } - } - } -} - -aggr Ureg -{ - 'U' 0 di; - 'U' 4 si; - 'U' 8 bp; - 'U' 12 nsp; - 'U' 16 bx; - 'U' 20 dx; - 'U' 24 cx; - 'U' 28 ax; - 'U' 32 gs; - 'U' 36 fs; - 'U' 40 es; - 'U' 44 ds; - 'U' 48 trap; - 'U' 52 ecode; - 'U' 56 pc; - 'U' 60 cs; - 'U' 64 flags; - { - 'U' 68 usp; - 'U' 68 sp; - }; - 'U' 72 ss; -}; - -defn -Ureg(addr) { - complex Ureg addr; - print(" di ", addr.di, "\n"); - print(" si ", addr.si, "\n"); - print(" bp ", addr.bp, "\n"); - print(" nsp ", addr.nsp, "\n"); - print(" bx ", addr.bx, "\n"); - print(" dx ", addr.dx, "\n"); - print(" cx ", addr.cx, "\n"); - print(" ax ", addr.ax, "\n"); - print(" gs ", addr.gs, "\n"); - print(" fs ", addr.fs, "\n"); - print(" es ", addr.es, "\n"); - print(" ds ", addr.ds, "\n"); - print(" trap ", addr.trap, "\n"); - print(" ecode ", addr.ecode, "\n"); - print(" pc ", addr.pc, "\n"); - print(" cs ", addr.cs, "\n"); - print(" flags ", addr.flags, "\n"); - print(" sp ", addr.sp, "\n"); - print(" ss ", addr.ss, "\n"); -}; -sizeofUreg = 76; - -aggr Linkdebug -{ - 'X' 0 version; - 'X' 4 map; -}; - -aggr Linkmap -{ - 'X' 0 addr; - 'X' 4 name; - 'X' 8 dynsect; - 'X' 12 next; - 'X' 16 prev; -}; - -defn -linkdebug() -{ - local a; - - if !havesymbol("_DYNAMIC") then - return 0; - - a = _DYNAMIC; - while *a != 0 do { - if *a == 21 then // 21 == DT_DEBUG - return *(a+4); - a = a+8; - } - return 0; -} - -defn -dynamicmap() -{ - if systype == "linux" || systype == "freebsd" then { - local r, m, n; - - r = linkdebug(); - if r then { - complex Linkdebug r; - m = r.map; - n = 0; - while m != 0 && n < 100 do { - complex Linkmap m; - if m.name && *(m.name\b) && access(*(m.name\s)) then - print("textfile({\"", *(m.name\s), "\", ", m.addr\X, "});\n"); - m = m.next; - n = n+1; - } - } - } -} - -defn -acidmap() -{ -// dynamicmap(); - acidtypes(); -} - -print(acidfile); |