add experimental trace facilities

This commit is contained in:
Yanyan Jiang 2018-08-10 22:06:07 +08:00
parent 74ac665b6e
commit fdf7a82ad5
5 changed files with 75 additions and 27 deletions

View File

@ -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 ========================

View File

@ -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

View File

@ -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");
}

View File

@ -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);
}

View File

@ -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) ;