Module Name: src
Committed By: dyoung
Date: Tue Nov 3 05:08:19 UTC 2009
Modified Files:
src/sys/arch/i386/i386: copy.S
Added Files:
src/share/man/man9/man9.i386: return_address.9
src/sys/arch/i386/include: return.h
Log Message:
Add return_address(9) for reading the Nth return address from the call
stack.
To generate a diff of this commit:
cvs rdiff -u -r0 -r1.1 src/share/man/man9/man9.i386/return_address.9
cvs rdiff -u -r1.18 -r1.19 src/sys/arch/i386/i386/copy.S
cvs rdiff -u -r0 -r1.1 src/sys/arch/i386/include/return.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/i386/i386/copy.S
diff -u src/sys/arch/i386/i386/copy.S:1.18 src/sys/arch/i386/i386/copy.S:1.19
--- src/sys/arch/i386/i386/copy.S:1.18 Sat Mar 28 22:46:52 2009
+++ src/sys/arch/i386/i386/copy.S Tue Nov 3 05:08:18 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: copy.S,v 1.18 2009/03/28 22:46:52 rmind Exp $ */
+/* $NetBSD: copy.S,v 1.19 2009/11/03 05:08:18 dyoung Exp $ */
/* NetBSD: locore.S,v 1.34 2005/04/01 11:59:31 yamt Exp $ */
/*-
@@ -65,7 +65,7 @@
*/
#include <machine/asm.h>
-__KERNEL_RCSID(0, "$NetBSD: copy.S,v 1.18 2009/03/28 22:46:52 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: copy.S,v 1.19 2009/11/03 05:08:18 dyoung Exp $");
#include "assym.h"
@@ -131,6 +131,27 @@
ret
/*
+ * void *return_address(unsigned int level);
+ *
+ * The return address if level == 0, the return address of the caller
+ * `level' levels down the stack if level > 0.
+ */
+ENTRY(return_address)
+ movl %ebp,%eax /* frame pointer -> %eax */
+ movl 4(%esp),%ecx /* level -> %ecx */
+ cmpl $0,%ecx
+ je 2f
+1:
+.Lreturn_address_start:
+ movl (%eax),%eax /* next frame pointer */
+ decl %ecx
+ jnz 1b
+2:
+ movl 0x4(%eax),%eax
+.Lreturn_address_end:
+ ret
+
+/*
* int kcopy(const void *from, void *to, size_t len);
* Copy len bytes, abort on fault.
*/
@@ -296,6 +317,11 @@
popl %esi
ret
+/* LINTSTUB: Ignore */
+NENTRY(return_address_fault)
+ movl $0,%eax
+ ret
+
/*
* int copyoutstr(const void *from, void *to, size_t maxlen, size_t *lencopied);
* Copy a NUL-terminated string, at most maxlen characters long, into the
@@ -789,6 +815,10 @@
.long .Lx86_copyargs_end
.long _C_LABEL(x86_copyargs_fault)
+ .long .Lreturn_address_start
+ .long .Lreturn_address_end
+ .long _C_LABEL(return_address_fault)
+
.long 0 /* terminate */
.text
Added files:
Index: src/share/man/man9/man9.i386/return_address.9
diff -u /dev/null src/share/man/man9/man9.i386/return_address.9:1.1
--- /dev/null Tue Nov 3 05:08:19 2009
+++ src/share/man/man9/man9.i386/return_address.9 Tue Nov 3 05:08:18 2009
@@ -0,0 +1,88 @@
+.\" $NetBSD: return_address.9,v 1.1 2009/11/03 05:08:18 dyoung Exp $
+.\"
+.\" Copyright (c) 2009 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to The NetBSD Foundation
+.\" by David Young.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd November 2, 2009
+.Dt return_address 9 i386
+.Os
+.Sh NAME
+.Nm return_address
+.Nd return address
+.Sh SYNOPSIS
+.In i386/return.h
+.Ft void *
+.Fn return_address "unsigned int level"
+.Sh DESCRIPTION
+The
+.Nm
+function evaluates to the first return address on the call stack
+if
+.Fa level
+equals 0, or else
+to the return address for the stack frame
+.Fa level
+frames down.
+.Pp
+This function is intended to be called by diagnostic code to record
+the call stack.
+.Pp
+A special fault handler stops
+.Nm
+from crashing the kernel by examining a non-existent or corrupt stack
+frame.
+.Pp
+Kernel compilation options affect both the ability of
+.Nm
+to locate return addresses on the stack, and the programmer's
+ability to interpret the addresses.
+The compiler may optimize away the stack frame pointers that
+.Nm
+depends on.
+To use
+.Nm
+effecively, try a kernel configuration option such as
+.Bd -literal
+makeoptions DEBUG="-g -fno-omit-frame-pointer -fno-optimize-sibling-calls -O0"
+.Ed
+.Sh RETURN VALUES
+.Nm
+returns the
+requested return address, or
+.Dv NULL
+if it cannot dissect the call stack.
+.Sh CODE REFERENCES
+.Pa sys/arch/i386/i386/copy.S ,
+.Pa sys/arch/i386/include/return.h
+.Sh REFERENCES
+.Xr config 5
+.Sh HISTORY
+.Nm
+first appeared in
+.Nx 6.0 .
+.Sh AUTHORS
+.An "David Young" Aq [email protected]
Index: src/sys/arch/i386/include/return.h
diff -u /dev/null src/sys/arch/i386/include/return.h:1.1
--- /dev/null Tue Nov 3 05:08:19 2009
+++ src/sys/arch/i386/include/return.h Tue Nov 3 05:08:18 2009
@@ -0,0 +1,8 @@
+/* $NetBSD: return.h,v 1.1 2009/11/03 05:08:18 dyoung Exp $ */
+
+#ifndef _I386_RETURN_H_
+#define _I386_RETURN_H_
+
+void *return_address(unsigned int);
+
+#endif /* _I386_RETURN_H_ */