add experimental trace facilities
This commit is contained in:
parent
74ac665b6e
commit
fdf7a82ad5
15
am/amtrace.h
15
am/amtrace.h
|
@ -1,13 +1,22 @@
|
|||
#ifndef __AMTRACE_H__
|
||||
#define __AMTRACE_H__
|
||||
|
||||
struct _Trace {
|
||||
// payload of function calls
|
||||
typedef struct _CallArgs {
|
||||
uintptr_t a0, a1, a2, a3;
|
||||
} _CallArgs;
|
||||
|
||||
typedef union _Payload {
|
||||
_CallArgs args;
|
||||
uintptr_t retval;
|
||||
} _CallPayload;
|
||||
|
||||
struct _TraceEvent {
|
||||
uint8_t cpu;
|
||||
uint8_t type;
|
||||
uint16_t length;
|
||||
char payload[];
|
||||
} __attribute__((packed));
|
||||
typedef struct _Trace _Trace;
|
||||
typedef struct _TraceEvent _TraceEvent;
|
||||
|
||||
// ========================= trace components ========================
|
||||
|
||||
|
|
|
@ -62,11 +62,12 @@ void irqall();
|
|||
|
||||
// Tracing
|
||||
|
||||
static inline int traced() {
|
||||
static inline int traced(uint32_t req) {
|
||||
#ifdef TRACE_THIS
|
||||
uint32_t flags = trace_flags;
|
||||
if ( (flags & TRACE_THIS) && // the extension is being traced
|
||||
1) {
|
||||
(flags & req) // required flags are present
|
||||
) {
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
@ -75,24 +76,34 @@ static inline int traced() {
|
|||
|
||||
#include <klib.h> // TODO: don't do this.
|
||||
|
||||
#define trace_call(fn) \
|
||||
#define trace_call(fn, args) \
|
||||
do { \
|
||||
if (traced()) { \
|
||||
printf("Call " #fn " (%x)\n", (void *)fn); \
|
||||
if (traced(_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 { \
|
||||
if (traced()) { \
|
||||
printf("Return " #fn " (%x) -> %x\n", (void *)fn, (uintptr_t)retval); \
|
||||
if (traced(_TRACE_RET)) { \
|
||||
printf("[trace] ret " #fn " (%x) -> %x\n", (void *)fn, (uintptr_t)retval); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define trace_wrapper(rettype, func, args) \
|
||||
trace_call(func); \
|
||||
rettype ret = func args; \
|
||||
trace_ret(func, ret); \
|
||||
return ret;
|
||||
#define get_0(_0, _1, _2, _3, ...) ((uintptr_t)_0)
|
||||
#define get_1(_0, _1, _2, _3, ...) ((uintptr_t)_1)
|
||||
#define get_2(_0, _1, _2, _3, ...) ((uintptr_t)_2)
|
||||
#define get_3(_0, _1, _2, _3, ...) ((uintptr_t)_3)
|
||||
|
||||
#define trace_wrapper(rettype, stub, func, arglist, n, ...) \
|
||||
_CallArgs call_args = (_CallArgs) { .a0 = get_0(__VA_ARGS__, 0, 0, 0, 0), \
|
||||
.a1 = get_1(__VA_ARGS__, 0, 0, 0, 0), \
|
||||
.a2 = get_2(__VA_ARGS__, 0, 0, 0, 0), \
|
||||
.a3 = get_3(__VA_ARGS__, 0, 0, 0, 0), \
|
||||
}; \
|
||||
trace_call(stub, call_args); \
|
||||
rettype ret = func arglist; \
|
||||
trace_ret(stub, ret);
|
||||
|
||||
#endif
|
|
@ -158,9 +158,7 @@ void irq_handle(struct TrapFrame *tf) {
|
|||
// Call user handlers (registered in _asye_init)
|
||||
_Context *ret_ctx = &ctx;
|
||||
if (user_handler) {
|
||||
trace_call(user_handler);
|
||||
_Context *next = user_handler(ev, &ctx);
|
||||
trace_ret(user_handler, next);
|
||||
if (!next) {
|
||||
panic("return to a null context");
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ void cpu_initpte() { // called by all cpus
|
|||
}
|
||||
}
|
||||
|
||||
int _protect(_Protect *p) {
|
||||
int protect(_Protect *p) {
|
||||
PDE *upt = pgalloc();
|
||||
for (int i = 0; i < PGSIZE / sizeof(PDE *); i++) {
|
||||
upt[i] = kpt[i];
|
||||
|
@ -62,7 +62,7 @@ int _protect(_Protect *p) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void _unprotect(_Protect *p) {
|
||||
int unprotect(_Protect *p) {
|
||||
PDE *upt = p->ptr;
|
||||
for (uint32_t va = (uint32_t)prot_vm_range.start;
|
||||
va != (uint32_t)prot_vm_range.end;
|
||||
|
@ -73,10 +73,12 @@ void _unprotect(_Protect *p) {
|
|||
}
|
||||
}
|
||||
pgfree(upt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void _switch(_Protect *p) {
|
||||
int vm_switch(_Protect *p) {
|
||||
set_cr3(p->ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int map(_Protect *p, void *va, void *pa, int prot) {
|
||||
|
@ -105,7 +107,7 @@ int map(_Protect *p, void *va, void *pa, int prot) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
_Context *_ucontext(_Protect *p, _Area ustack, _Area kstack, void *entry, void *args) {
|
||||
_Context *ucontext(_Protect *p, _Area ustack, _Area kstack, void *entry, void *args) {
|
||||
_Context *ctx = (_Context*)kstack.start;
|
||||
*ctx = (_Context) {
|
||||
.cs = USEL(SEG_UCODE), .eip = (uint32_t)entry, .eflags = FL_IF,
|
||||
|
@ -130,10 +132,27 @@ static void pgfree(void *ptr) {
|
|||
pgfree_usr(ptr);
|
||||
}
|
||||
|
||||
int _pte_init(void * (*pgalloc_f)(size_t), void (*pgfree_f)(void *)) {
|
||||
trace_wrapper(int, pte_init, (pgalloc_f, pgfree_f)) ;
|
||||
}
|
||||
// wrappers
|
||||
|
||||
int _pte_init(void * (*pgalloc_f)(size_t), void (*pgfree_f)(void *)) {
|
||||
trace_wrapper(int, _pte_init, pte_init, (pgalloc_f, pgfree_f), 2, pgalloc_f, pgfree_f) ;
|
||||
return ret;
|
||||
}
|
||||
int _map(_Protect *p, void *va, void *pa, int prot) {
|
||||
trace_wrapper(int, map, (p, va, pa, prot));
|
||||
trace_wrapper(int, _map, map, (p, va, pa, prot), 4, p, va, pa, prot);
|
||||
return ret;
|
||||
}
|
||||
_Context *_ucontext(_Protect *p, _Area ustack, _Area kstack, void *entry, void *args) {
|
||||
trace_wrapper(_Context *, _ucontext, ucontext, (p, ustack, kstack, entry, args), 3, p, entry, args);
|
||||
return ret;
|
||||
}
|
||||
void _switch(_Protect *p) {
|
||||
trace_wrapper(int, _switch, vm_switch, (p), 1, p);
|
||||
}
|
||||
int _protect(_Protect *p) {
|
||||
trace_wrapper(int, _protect, protect, (p), 1, p);
|
||||
return ret;
|
||||
}
|
||||
void _unprotect(_Protect *p) {
|
||||
trace_wrapper(int, _unprotect, unprotect, (p), 1, p);
|
||||
}
|
|
@ -31,10 +31,10 @@ _Protect prot;
|
|||
|
||||
int main() {
|
||||
st = (uintptr_t)_heap.start;
|
||||
_trace_on(_TRACE_PTE);
|
||||
_trace_on(_TRACE_PTE | _TRACE_FUNC);
|
||||
_asye_init(ihandle);
|
||||
_pte_init(alloc, free);
|
||||
print("Hello World!\n");
|
||||
printf(">>> pte init done.\n");
|
||||
|
||||
_protect(&prot);
|
||||
|
||||
|
@ -44,9 +44,20 @@ int main() {
|
|||
int pgsz = 4096;
|
||||
|
||||
_map(&prot, ptr, alloc(pgsz), _PROT_WRITE);
|
||||
|
||||
printf(">>> no longer trace function returns\n");
|
||||
_trace_off(_TRACE_RET);
|
||||
|
||||
_map(&prot, ptr + pgsz, alloc(pgsz), _PROT_WRITE);
|
||||
|
||||
static char kstk[4096];
|
||||
_Area k = { .start = kstk, .end = kstk + 4096 };
|
||||
_Area u = { .start = ptr + pgsz, .end = ptr + pgsz * 2 };
|
||||
|
||||
_ucontext(&prot, u, k, ptr, (void*)-1);
|
||||
|
||||
_switch(&prot);
|
||||
_unprotect(&prot);
|
||||
|
||||
_intr_write(1);
|
||||
while (1) ;
|
||||
|
|
Loading…
Reference in New Issue