// trace user malloc pool - trace malloc, realloc, and free calls // if trumpsbrk is set, we trace sbrkalloc and sbrkmerge too. _stoprunning = 0; trumphexaddrs = 0; trumpsbrk = 0; defn stopped(pid) { local l; local pc; pc = *PC; if notes then { if (notes[0]!="sys: breakpoint") then { print(pid,": ",reason(*TRAP),"\t"); print(fmt(pc,97),"\t",fmt(pc,105),"\n"); print("Notes pending:\n"); l = notes; while l do { print("\t",head l,"\n"); l = tail l; } _stoprunning = 1; } } } defn printstack() { local frame, stk, pcs, lst, x; pcs = {*PC}; stk = strace(*PC,*SP,0); while stk do { pcs = append pcs, stk[0][1]; stk = tail stk; } print(" #"); lst = pcs; while lst do { if trumphexaddrs != 0 then x = lst[0]\X; else x = lst[0]\a; print(" src(", x, ");"); lst = tail lst; } print("\n"); } defn setuptrump() { mallocPC = malloc; malloczPC = mallocz; freePC = free; reallocPC = realloc; sbrkallocPC = sbrkalloc; sbrkmergePC = sbrkmerge; // linker might fill delay slot with first instruction if objtype == "mips" then { mallocPC = mallocPC+4; malloczPC = malloczPC+4; freePC = freePC+4; reallocPC = reallocPC+4; sbrkallocPC = sbrkallocPC+4; sbrkmergePC = sbrkmergePC+4; } bpset(mallocPC); bpset(malloczPC); bpset(freePC); bpset(reallocPC); if trumpsbrk then { bpset(sbrkallocPC); bpset(sbrkmergePC); } } defn cleantrump() { stop(pid); bpdel(mallocPC); bpdel(malloczPC); bpdel(freePC); bpdel(reallocPC); bpdel(sbrkallocPC); bpdel(sbrkmergePC); } defn trumpflush() { stop(pid); // already stopped, but flushes output } defn new() { bplist = {}; newproc(progargs); bpset(follow(main)[0]); cont(); bpdel(*PC); // clear the hang bit, which is left set by newproc, so programs we fork/exec don't hang printto("/proc/"+itoa(pid)+"/ctl", "nohang"); } defn trumpfninfo() { local arg0, arg1, stk, retpc, params; stk = strace(*PC, *SP, 0); retpc = stk[0][1]; params = stk[0][2]; arg0 = params[0][1]; arg1 = 0; if tail params != {} then arg1 = params[1][1]; return {arg0, arg1, retpc}; } defn trumpretval() { if objtype=="386" then return *AX; if objtype=="mips" then return *R1; if objtype=="power" || objtype=="alpha" then return *R0; } defn trump() { local arg0, arg1, pc, ret, x; stop(pid); _stoprunning = 0; setuptrump(); while !_stoprunning do { cont(); if notes[0]!="sys: breakpoint" then { cleantrump(); return {}; } pc = *PC; x = trumpfninfo(); arg0 = x[0]; if pc == reallocPC || pc == sbrkmergePC then arg1 = x[1]; bpset(x[2]); cont(); bpdel(x[2]); ret = trumpretval(); if pc == mallocPC then print(ret\X, " malloc ", arg0\D); if pc == malloczPC then print(ret\X, " mallocz ", arg0\D); if pc == freePC then print(arg0\X, " free"); if pc == reallocPC then print(ret\X, " realloc ", arg0\X, " ", arg1\D); if pc == sbrkallocPC then print(ret\X, " sbrkalloc ", arg0\D); if pc == sbrkmergePC then print("sbrkmerge ", arg0\X, " ", arg1\X, " = ", ret\D); printstack(); trumpflush(); } } defn untrump() { cleantrump(); start(pid); } print("/sys/lib/acid/trump");