17d9195a7SDavid du Colombier #include <u.h>
27d9195a7SDavid du Colombier #include <libc.h>
37d9195a7SDavid du Colombier #include <bio.h>
47d9195a7SDavid du Colombier #include <mach.h>
57d9195a7SDavid du Colombier #define Extern extern
67d9195a7SDavid du Colombier #include "power.h"
77d9195a7SDavid du Colombier
87d9195a7SDavid du Colombier #define STRINGSZ 128
97d9195a7SDavid du Colombier
107d9195a7SDavid du Colombier /*
117d9195a7SDavid du Colombier * print the value of dot as file:line
127d9195a7SDavid du Colombier */
137d9195a7SDavid du Colombier void
printsource(long dot)147d9195a7SDavid du Colombier printsource(long dot)
157d9195a7SDavid du Colombier {
167d9195a7SDavid du Colombier char str[STRINGSZ];
177d9195a7SDavid du Colombier
187d9195a7SDavid du Colombier if (fileline(str, STRINGSZ, dot))
197d9195a7SDavid du Colombier Bprint(bioout, "%s", str);
207d9195a7SDavid du Colombier }
217d9195a7SDavid du Colombier
227d9195a7SDavid du Colombier void
printlocals(Symbol * fn,ulong fp)237d9195a7SDavid du Colombier printlocals(Symbol *fn, ulong fp)
247d9195a7SDavid du Colombier {
257d9195a7SDavid du Colombier int i;
267d9195a7SDavid du Colombier Symbol s;
277d9195a7SDavid du Colombier
287d9195a7SDavid du Colombier s = *fn;
297d9195a7SDavid du Colombier for (i = 0; localsym(&s, i); i++) {
307d9195a7SDavid du Colombier if (s.class != CAUTO)
317d9195a7SDavid du Colombier continue;
327d9195a7SDavid du Colombier Bprint(bioout, "\t%s=#%lux\n", s.name, getmem_4(fp-s.value));
337d9195a7SDavid du Colombier }
347d9195a7SDavid du Colombier }
357d9195a7SDavid du Colombier
367d9195a7SDavid du Colombier void
printparams(Symbol * fn,ulong fp)377d9195a7SDavid du Colombier printparams(Symbol *fn, ulong fp)
387d9195a7SDavid du Colombier {
397d9195a7SDavid du Colombier int i;
407d9195a7SDavid du Colombier Symbol s;
417d9195a7SDavid du Colombier int first;
427d9195a7SDavid du Colombier
437d9195a7SDavid du Colombier fp += mach->szreg; /* skip saved pc */
447d9195a7SDavid du Colombier s = *fn;
457d9195a7SDavid du Colombier for (first = i = 0; localsym(&s, i); i++) {
467d9195a7SDavid du Colombier if (s.class != CPARAM)
477d9195a7SDavid du Colombier continue;
487d9195a7SDavid du Colombier if (first++)
497d9195a7SDavid du Colombier Bprint(bioout, ", ");
507d9195a7SDavid du Colombier Bprint(bioout, "%s=#%lux", s.name, getmem_4(fp+s.value));
517d9195a7SDavid du Colombier }
527d9195a7SDavid du Colombier Bprint(bioout, ") ");
537d9195a7SDavid du Colombier }
547d9195a7SDavid du Colombier
557d9195a7SDavid du Colombier #define STARTSYM "_main"
567d9195a7SDavid du Colombier #define FRAMENAME ".frame"
577d9195a7SDavid du Colombier
587d9195a7SDavid du Colombier void
stktrace(int modif)597d9195a7SDavid du Colombier stktrace(int modif)
607d9195a7SDavid du Colombier {
617d9195a7SDavid du Colombier ulong pc, sp;
627d9195a7SDavid du Colombier Symbol s, f;
637d9195a7SDavid du Colombier int i;
647d9195a7SDavid du Colombier char buf[512];
657d9195a7SDavid du Colombier
667d9195a7SDavid du Colombier pc = reg.pc;
677d9195a7SDavid du Colombier sp = reg.r[1];
687d9195a7SDavid du Colombier i = 0;
697d9195a7SDavid du Colombier while (findsym(pc, CTEXT, &s)) {
707d9195a7SDavid du Colombier if(strcmp(STARTSYM, s.name) == 0) {
71*f19e7b74SDavid du Colombier Bprint(bioout, "%s() at #%llux\n", s.name, s.value);
727d9195a7SDavid du Colombier break;
737d9195a7SDavid du Colombier }
747d9195a7SDavid du Colombier if (pc == s.value) /* at first instruction */
757d9195a7SDavid du Colombier f.value = 0;
767d9195a7SDavid du Colombier else if (findlocal(&s, FRAMENAME, &f) == 0)
777d9195a7SDavid du Colombier break;
787d9195a7SDavid du Colombier if (s.type == 'L' || s.type == 'l' || pc <= s.value+4)
797d9195a7SDavid du Colombier pc = reg.lr;
807d9195a7SDavid du Colombier else pc = getmem_4(sp);
817d9195a7SDavid du Colombier sp += f.value;
827d9195a7SDavid du Colombier Bprint(bioout, "%s(", s.name);
837d9195a7SDavid du Colombier printparams(&s, sp);
847d9195a7SDavid du Colombier printsource(s.value);
857d9195a7SDavid du Colombier Bprint(bioout, " called from ");
867d9195a7SDavid du Colombier symoff(buf, sizeof(buf), pc-4, CTEXT);
877d9195a7SDavid du Colombier Bprint(bioout, buf);
887d9195a7SDavid du Colombier printsource(pc-8);
897d9195a7SDavid du Colombier Bprint(bioout, "\n");
907d9195a7SDavid du Colombier if(modif == 'C')
917d9195a7SDavid du Colombier printlocals(&s, sp);
927d9195a7SDavid du Colombier if(++i > 40){
937d9195a7SDavid du Colombier Bprint(bioout, "(trace truncated)\n");
947d9195a7SDavid du Colombier break;
957d9195a7SDavid du Colombier }
967d9195a7SDavid du Colombier }
977d9195a7SDavid du Colombier }
98