summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2013-06-03 21:35:42 +0200
committerRichard Braun <rbraun@sceen.net>2013-06-03 21:36:06 +0200
commit7b712748e94fadbcb9131c5c1b19caa3d360db5c (patch)
tree2a04067dbc0c850f7d2ab2475e92b3b092c6e336
parent556c2c3b96f848d407ad002af434eee309dcc9b3 (diff)
x86/tcb: new tcb_trace function
This function dumps the stack trace of a thread from its TCB. In order to do that, the base pointer is now included in the TCB, along with the stack and instruction pointers.
-rw-r--r--arch/x86/machine/tcb.c10
-rw-r--r--arch/x86/machine/tcb.h10
-rw-r--r--arch/x86/machine/tcb_asm.S38
3 files changed, 37 insertions, 21 deletions
diff --git a/arch/x86/machine/tcb.c b/arch/x86/machine/tcb.c
index 90f08b58..14d74c67 100644
--- a/arch/x86/machine/tcb.c
+++ b/arch/x86/machine/tcb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Richard Braun.
+ * Copyright (c) 2012, 2013 Richard Braun.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,6 +19,7 @@
#include <kern/macros.h>
#include <kern/param.h>
#include <machine/cpu.h>
+#include <machine/strace.h>
#include <machine/tcb.h>
/*
@@ -32,6 +33,7 @@ tcb_init(struct tcb *tcb, void *stack, void (*fn)(void))
{
void **ptr;
+ tcb->bp = 0;
tcb->sp = (unsigned long)stack + STACK_SIZE - sizeof(unsigned long);
tcb->ip = (unsigned long)tcb_start;
@@ -49,6 +51,12 @@ tcb_load(struct tcb *tcb)
}
void
+tcb_trace(const struct tcb *tcb)
+{
+ strace_show(tcb->ip, tcb->bp);
+}
+
+void
tcb_reschedule_intr(struct trap_frame *frame)
{
(void)frame;
diff --git a/arch/x86/machine/tcb.h b/arch/x86/machine/tcb.h
index 886237ee..bd0a793d 100644
--- a/arch/x86/machine/tcb.h
+++ b/arch/x86/machine/tcb.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Richard Braun.
+ * Copyright (c) 2012, 2013 Richard Braun.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -31,6 +31,7 @@
* Architecture specific thread data.
*/
struct tcb {
+ unsigned long bp;
unsigned long sp;
unsigned long ip;
};
@@ -82,6 +83,13 @@ tcb_switch(struct tcb *prev, struct tcb *next)
}
/*
+ * Dump the stack trace of a TCB.
+ *
+ * The thread associated to the TCB should not be running.
+ */
+void tcb_trace(const struct tcb *tcb);
+
+/*
* Send a rescheduling interrupt to a remote processor.
*/
static inline void
diff --git a/arch/x86/machine/tcb_asm.S b/arch/x86/machine/tcb_asm.S
index 815dc365..2089e939 100644
--- a/arch/x86/machine/tcb_asm.S
+++ b/arch/x86/machine/tcb_asm.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Richard Braun.
+ * Copyright (c) 2012, 2013 Richard Braun.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,8 +24,9 @@
#ifdef __LP64__
ASM_ENTRY(tcb_context_load)
- movq 8(%rdi), %rax
- movq (%rdi), %rsp
+ movq (%rdi), %rbp
+ movq 8(%rdi), %rsp
+ movq 16(%rdi), %rax
pushq $CPU_EFL_ONE
popfq
jmp *%rax
@@ -35,8 +36,9 @@ ASM_END(tcb_context_load)
ASM_ENTRY(tcb_context_load)
movl 4(%esp), %eax
- movl 4(%eax), %ecx
- movl (%eax), %esp
+ movl (%eax), %ebp
+ movl 4(%eax), %esp
+ movl 8(%eax), %ecx
pushl $CPU_EFL_ONE
popfl
jmp *%ecx
@@ -50,7 +52,6 @@ ASM_END(tcb_context_load)
ASM_ENTRY(tcb_start)
popq %rax
- xorq %rbp, %rbp
call *%rax
/* Never reached */
@@ -60,15 +61,16 @@ ASM_END(tcb_start)
ASM_ENTRY(tcb_context_switch)
pushfq
pushq %rbx
- pushq %rbp
pushq %r12
pushq %r13
pushq %r14
pushq %r15
- movq %rsp, (%rdi)
- movq $1f, 8(%rdi)
- movq (%rsi), %rsp
- movq 8(%rsi), %rax
+ movq %rbp, (%rdi)
+ movq %rsp, 8(%rdi)
+ movq $1f, 16(%rdi)
+ movq (%rsi), %rbp
+ movq 8(%rsi), %rsp
+ movq 16(%rsi), %rax
jmp *%rax
1:
@@ -76,7 +78,6 @@ ASM_ENTRY(tcb_context_switch)
popq %r14
popq %r13
popq %r12
- popq %rbp
popq %rbx
popfq
ret
@@ -86,7 +87,6 @@ ASM_END(tcb_context_switch)
ASM_ENTRY(tcb_start)
popl %eax
- xorl %ebp, %ebp
call *%eax
/* Never reached */
@@ -98,19 +98,19 @@ ASM_ENTRY(tcb_context_switch)
movl 8(%esp), %ecx
pushfl
pushl %ebx
- pushl %ebp
pushl %edi
pushl %esi
- movl %esp, (%eax)
- movl $1f, 4(%eax)
- movl (%ecx), %esp
- movl 4(%ecx), %edx
+ movl %ebp, (%eax)
+ movl %esp, 4(%eax)
+ movl $1f, 8(%eax)
+ movl (%ecx), %ebp
+ movl 4(%ecx), %esp
+ movl 8(%ecx), %edx
jmp *%edx
1:
popl %esi
popl %edi
- popl %ebp
popl %ebx
popfl
ret