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_ */

Reply via email to