a much better tracing code
This commit is contained in:
parent
87ea80951b
commit
5c5d3ad03f
2
am/am.h
2
am/am.h
|
@ -89,7 +89,7 @@ void _intr_write(int enable);
|
|||
int _pte_init(void *(*pgalloc)(size_t size), void (*pgfree)(void *));
|
||||
int _protect(_Protect *p);
|
||||
void _unprotect(_Protect *p);
|
||||
void _switch(_Protect *p);
|
||||
void _prot_switch(_Protect *p);
|
||||
int _map(_Protect *p, void *va, void *pa, int prot);
|
||||
_Context *_ucontext(_Protect *p, _Area ustack, _Area kstack,
|
||||
void *entry, void *args);
|
||||
|
|
|
@ -60,50 +60,4 @@ void vec14();
|
|||
void vecsys();
|
||||
void irqall();
|
||||
|
||||
// Tracing
|
||||
|
||||
#include <klib.h> // TODO: don't do this.
|
||||
|
||||
#define should_trace(flags, req) ( \
|
||||
(flags & TRACE_THIS) && \
|
||||
(flags & req) \
|
||||
)
|
||||
|
||||
#define trace_call(fn, args) \
|
||||
do { \
|
||||
uint32_t flags = trace_flags; \
|
||||
if (should_trace(flags, _TRACE_CALL)) { \
|
||||
printf("[trace] call " #fn " (%x) with args {%x, %x, %x, %x}\n", (void *)fn, \
|
||||
args.a0, args.a1, args.a2, args.a3); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define trace_ret(fn, retval) \
|
||||
do { \
|
||||
uint32_t flags = trace_flags; \
|
||||
if (should_trace(flags, _TRACE_RET)) { \
|
||||
printf("[trace] ret " #fn " (%x) -> %x\n", (void *)fn, (uintptr_t)retval); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define CALL_ARGS(_0, _1, _2, _3, ...) \
|
||||
(_CallArgs) { .a0 = ((uintptr_t)_0), \
|
||||
.a1 = ((uintptr_t)_1), \
|
||||
.a2 = ((uintptr_t)_2), \
|
||||
.a3 = ((uintptr_t)_3), } \
|
||||
|
||||
#define trace_wrapper_noret(rettype, stub, func, arglist, n, ...) \
|
||||
trace_call(stub, CALL_ARGS(__VA_ARGS__, 0, 0, 0, 0)); \
|
||||
rettype ret = func arglist; \
|
||||
trace_ret(stub, ret);
|
||||
|
||||
#define trace_wrapper(rettype, stub, func, arglist, n, ...) \
|
||||
trace_wrapper_noret(rettype, stub, func, arglist, n, __VA_ARGS__); \
|
||||
return ret;
|
||||
|
||||
#define TRACE_NORET(stub, func, decl, arglist, n, ...) \
|
||||
void stub decl { trace_wrapper_noret(int, stub, func, arglist, n, __VA_ARGS__); }
|
||||
|
||||
#define TRACE(rettype, stub, func, decl, arglist, n, ...) \
|
||||
rettype stub decl { trace_wrapper(rettype, stub, func, arglist, n, __VA_ARGS__); }
|
||||
#endif
|
||||
|
|
|
@ -75,7 +75,7 @@ int unprotect(_Protect *p) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int vm_switch(_Protect *p) {
|
||||
int prot_switch(_Protect *p) {
|
||||
set_cr3(p->ptr);
|
||||
return 0;
|
||||
}
|
||||
|
@ -129,4 +129,4 @@ static void *pgalloc() {
|
|||
|
||||
static void pgfree(void *ptr) {
|
||||
pgfree_usr(ptr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,41 +11,80 @@ void _trace_off(uint32_t flags) {
|
|||
trace_flags &= ~flags;
|
||||
}
|
||||
|
||||
// wrappers of traced functions
|
||||
// TODO: add others, add pgalloc()/pgfree() callback traces
|
||||
#include <klib.h> // TODO: don't do this.
|
||||
|
||||
// ASYE
|
||||
int asye_init(_Context *(*handler)(_Event, _Context *));
|
||||
_Context *kcontext(_Area stack, void (*entry)(void *), void *arg);
|
||||
int yield();
|
||||
int intr_read();
|
||||
int intr_write(int enable);
|
||||
_Context *irq_callback(_Event ev, _Context *ctx);
|
||||
// PTE
|
||||
int pte_init(void * (*pgalloc_f)(size_t), void (*pgfree_f)(void *));
|
||||
int map(_Protect *p, void *va, void *pa, int prot);
|
||||
_Context *ucontext(_Protect *p, _Area ustack, _Area kstack, void *entry, void *args);
|
||||
int vm_switch(_Protect *p);
|
||||
int protect(_Protect *p);
|
||||
int unprotect(_Protect *p);
|
||||
// MPE
|
||||
#define should_trace(flags, req) ( \
|
||||
(flags & TRACE_THIS) && \
|
||||
(flags & req) \
|
||||
)
|
||||
|
||||
// ==================== wrapper implementations ====================
|
||||
#define trace_call(fn, args) \
|
||||
do { \
|
||||
uint32_t flags = trace_flags; \
|
||||
if (should_trace(flags, _TRACE_CALL)) { \
|
||||
printf("[trace] call " #fn " (%x) with args {%x, %x, %x, %x}\n", (void *)fn, \
|
||||
args.a0, args.a1, args.a2, args.a3); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define trace_ret(fn, retval) \
|
||||
do { \
|
||||
uint32_t flags = trace_flags; \
|
||||
if (should_trace(flags, _TRACE_RET)) { \
|
||||
printf("[trace] ret " #fn " (%x) -> %x\n", (void *)fn, (uintptr_t)retval); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define CALL_ARGS(_0, _1, _2, _3, ...) \
|
||||
(_CallArgs) { .a0 = ((uintptr_t)_0), \
|
||||
.a1 = ((uintptr_t)_1), \
|
||||
.a2 = ((uintptr_t)_2), \
|
||||
.a3 = ((uintptr_t)_3), } \
|
||||
|
||||
#define trace_wrapper_noret(rettype, stub, func, arglist, n, ...) \
|
||||
trace_call(stub, CALL_ARGS(__VA_ARGS__, 0, 0, 0, 0)); \
|
||||
rettype ret = func arglist; \
|
||||
trace_ret(stub, ret);
|
||||
|
||||
#define trace_wrapper(rettype, stub, func, arglist, n, ...) \
|
||||
trace_wrapper_noret(rettype, stub, func, arglist, n, __VA_ARGS__); \
|
||||
return ret;
|
||||
|
||||
#define TRACE_NORET(rettype, stub, func, decl, arglist, n, ...) \
|
||||
void stub decl { trace_wrapper_noret(int, stub, func, arglist, n, __VA_ARGS__); }
|
||||
|
||||
#define TRACE(rettype, stub, func, decl, arglist, n, ...) \
|
||||
rettype stub decl { trace_wrapper(rettype, stub, func, arglist, n, __VA_ARGS__); }
|
||||
|
||||
#define DECL(tr, rettype, func, decl, args, ...) \
|
||||
rettype func decl ;
|
||||
|
||||
#define DEF(tr, rettype, func, decl, args, ...) \
|
||||
tr(rettype, _##func, func, decl, args, __VA_ARGS__)
|
||||
|
||||
#define ASYE_FUNCS(_) \
|
||||
_(TRACE, int, asye_init, (_Context *(*handler)(_Event, _Context *)), (handler), 1, handler) \
|
||||
_(TRACE, _Context *, kcontext, (_Area stack, void (*entry)(void *), void *arg), (stack, entry, arg), 2, entry, arg) \
|
||||
_(TRACE, int, intr_read, (), (), 1, 0) \
|
||||
_(TRACE, _Context *, irq_callback, (_Event ev, _Context *ctx), (ev, ctx), 4, ev.event, ev.cause, ev.ref, ctx); \
|
||||
_(TRACE_NORET, int, yield, (), (), 1, 0) \
|
||||
_(TRACE_NORET, int, intr_write, (int enable), (enable), 1, enable)
|
||||
|
||||
#define PTE_FUNCS(_) \
|
||||
_(TRACE, int, pte_init, (void * (*pgalloc_f)(size_t), void (*pgfree_f)(void *)), (pgalloc_f, pgfree_f), 2, pgalloc_f, pgfree_f) \
|
||||
_(TRACE, int, map, (_Protect *p, void *va, void *pa, int prot), (p, va, pa, prot), 4, p, va, pa, prot) \
|
||||
_(TRACE, _Context *, ucontext, (_Protect *p, _Area ustack, _Area kstack, void *entry, void *args), (p, ustack, kstack, entry, args), 3, p, entry, args) \
|
||||
_(TRACE_NORET, int, prot_switch, (_Protect *p), (p), 1, p) \
|
||||
_(TRACE, int, protect, (_Protect *p), (p), 1, p) \
|
||||
_(TRACE_NORET, int, unprotect, (_Protect *p), (p), 1, p)
|
||||
|
||||
ASYE_FUNCS(DECL)
|
||||
PTE_FUNCS(DECL)
|
||||
|
||||
#define TRACE_THIS _TRACE_ASYE
|
||||
TRACE(int, _asye_init, asye_init, (_Context *(*handler)(_Event, _Context *)), (handler), 1, handler);
|
||||
TRACE(_Context *, _kcontext, kcontext, (_Area stack, void (*entry)(void *), void *arg), (stack, entry, arg), 2, entry, arg);
|
||||
TRACE_NORET(_yield, yield, (), (), 1, 0);
|
||||
TRACE(int, _intr_read, intr_read, (), (), 1, 0);
|
||||
TRACE_NORET(_intr_write, intr_write, (int enable), (enable), 1, enable)
|
||||
TRACE(_Context *, _irq_callback, irq_callback, (_Event ev, _Context *ctx), (ev, ctx), 4, ev.event, ev.cause, ev.ref, ctx);
|
||||
ASYE_FUNCS(DEF)
|
||||
#undef TRACE_THIS
|
||||
|
||||
#define TRACE_THIS _TRACE_PTE
|
||||
TRACE(int, _pte_init, pte_init, (void * (*pgalloc_f)(size_t), void (*pgfree_f)(void *)), (pgalloc_f, pgfree_f), 2, pgalloc_f, pgfree_f) ;
|
||||
TRACE(int, _map, map, (_Protect *p, void *va, void *pa, int prot), (p, va, pa, prot), 4, p, va, pa, prot);
|
||||
TRACE(_Context *, _ucontext, ucontext, (_Protect *p, _Area ustack, _Area kstack, void *entry, void *args), (p, ustack, kstack, entry, args), 3, p, entry, args);
|
||||
TRACE_NORET(_switch, vm_switch, (_Protect *p), (p), 1, p)
|
||||
TRACE(int, _protect, protect, (_Protect *p), (p), 1, p);
|
||||
TRACE_NORET(_unprotect, unprotect, (_Protect *p), (p), 1, p);
|
||||
PTE_FUNCS(DEF)
|
||||
#undef TRACE_THIS
|
||||
|
|
|
@ -56,7 +56,7 @@ int main() {
|
|||
|
||||
_ucontext(&prot, u, k, ptr, (void*)-1);
|
||||
|
||||
_switch(&prot);
|
||||
_prot_switch(&prot);
|
||||
_unprotect(&prot);
|
||||
|
||||
_yield();
|
||||
|
|
Loading…
Reference in New Issue