forked from libunwind/libunwind
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
mostang.com!davidm
committed
Feb 15, 2002
1 parent
63669f7
commit 7fbfe0a
Showing
36 changed files
with
5,984 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
davidm@panda.mostang.com |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
2002-01-18 David Mosberger-Tang <David.Mosberger@acm.org> | ||
|
||
* src/ia64/parser.c (__ia64_unw_create_state_record): Set | ||
IA64_FLAG_HAS_HANDLER if the unwind info descriptors indicate that | ||
there a handler. | ||
|
||
* src/ia64/regs.c (__ia64_access_reg): Return zero for UNW_REG_HANDLER | ||
in frames that don't have a personality routine. | ||
|
||
* src/ia64/unwind_i.h (IA64_FLAG_HAS_HANDLER): New flag. | ||
|
||
* src/ia64/regs.c (__ia64_access_reg): When reading UNW_REG_HANDLER, | ||
account for the fact that the personality address is gp-relative. | ||
|
||
* src/ia64/parser.c (__ia64_unw_create_state_record): Fix | ||
initialization of segbase and len. | ||
|
||
2002-01-17 David Mosberger-Tang <David.Mosberger@acm.org> | ||
|
||
* include/unwind-ia64.h: Include via "unwind.h" to ensure | ||
the file is picked up from same directory. | ||
|
||
2002-01-16 David Mosberger-Tang <David.Mosberger@acm.org> | ||
|
||
* include/unwind.h: Define UNW_ESTOPUNWIND. This error code may | ||
be returned by acquire_unwind_info() to force termination of | ||
unwinding. An application may want to do this when encountering a | ||
call frame for dynamically generated code, for example. | ||
|
||
* unwind.h: Pass opaque argument pointer to acquire_unwind_info() | ||
and release_unwind_info() like we do for access_mem() etc. | ||
|
||
2002-01-14 David Mosberger-Tang <David.Mosberger@acm.org> | ||
|
||
* Version 0.0 released. | ||
|
||
2002-01-11 David Mosberger-Tang <David.Mosberger@acm.org> | ||
|
||
* ChangeLog created. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
The central data structure of the unwind API is the unwind cursor. | ||
This structure tracks the frame registers and the preserved registers. | ||
The distinction between frame registers and preserved registers is | ||
important: the former represent the *current* value of a register (as | ||
it existed at the current IP); the latter represent the *saved* value | ||
of a register (i.e., the value that existed on entry to the current | ||
procedure). The unwind API defines a handful of well-known frame | ||
"registers": | ||
|
||
- ip: the instruction pointer (pc) | ||
- rp: the return pointer (rp, aka "return address" or "return link") | ||
- sp: the stack pointer (memory stack pointer, in the case of ia64) | ||
- fp: the frame pointer | ||
- first_ip: the starting address of the current "procedure" | ||
- handler: a pointer to an architecture & language-specific | ||
"personality" routine | ||
- lsda: a pointer to an architecture & language-specific | ||
data-area | ||
|
||
The API defines no well-known preserved registers. Each architecture | ||
can define additional registers as needed. Of course, a portable | ||
application may only rely on well-known registers. The names for | ||
preserved registers are defined in the architecture-specific header | ||
file <unwind-ARCH.h>. For example, to get the IA-64-specific register | ||
names, an application would do: | ||
|
||
#include <unwind-ia64.h> | ||
|
||
The API is designed to handle two primary cases: unwinding within the | ||
current (local) process and unwinding of another ("remote") process | ||
(e.g., through ptrace()). In the local case, the initial machine | ||
state is captured by an unwind context (currently the same as | ||
ucontext_t). In the remote case, the initial machine state is | ||
captured by an unwind accessor structure, which provides callback | ||
routines for reading/writing memory and registers and for obtaining | ||
unwind information. | ||
|
||
Once a cursor has been initialized, you can step through the call | ||
chain with the unw_step() routine. The frame registers and the | ||
preserved state can then be accessed with unw_get_reg() or modified | ||
with unw_set_reg(). For floating-point registers, there are separate | ||
unw_get_fpreg() and unw_set_fpreg() routines (on some arches, e.g., | ||
Alpha, these could be just aliases for unw_{g,s}et_reg()). The | ||
unw_resume() routine can be used to resume execution at an arbitrary | ||
point in the call-chain (as identified by an unwind cursor). This is | ||
intended for exception handling and, at least for now, the intention | ||
is to support this routine only for the local case. Kevin, if you | ||
feel gdb could benefit from such a routine, I'd be interested to hear | ||
about it. | ||
|
||
Note that it is perfectly legal to make copies of the unwind cursor. | ||
This makes it possible, e.g., to obtain an unwind context, modify the | ||
state in an earlier call frame, and then resume execution at the point | ||
at which the unwind context was captured. | ||
|
||
Here is a quick example of how to use the unwind API to do a simple | ||
stack trace: | ||
|
||
unw_cursor_t cursor; | ||
unw_word_t ip, sp; | ||
ucontext_t uc; | ||
|
||
getcontext(&uc); | ||
unw_init_local(&cursor, &uc); | ||
do | ||
{ | ||
unw_get_reg(&cursor, UNW_REG_IP, &ip); | ||
unw_get_reg(&cursor, UNW_REG_SP, &sp); | ||
printf ("ip=%016lx sp=%016lx\n", ip, sp); | ||
} | ||
while (unw_step (&cursor) > 0); | ||
|
||
Note that this particular example should work on pretty much any | ||
architecture, as it doesn't rely on any arch-specific registers. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
This is version 0.0 of the unwind library. At the moment, only the | ||
IA-64 Linux (IPF Linux) platform is supported and even that support | ||
has received only light testing. Consequently, this release is | ||
intended primarily to expose the unwind API to more developers and to | ||
collect feedback on what does and does not work. Having said that, | ||
backtracing through gcc-generated code might work reasonably well. | ||
|
||
There is virtually no documentation at the moment. A brief outline of | ||
the unwind API is in file NOTES. To get a feel for how things are | ||
intended to work, you may also want to take a look at include/unwind.h | ||
and include/unwind-ia64.h. Finally, the test program in | ||
src/tests/bt.c shows two ways of how to do a simple backtrace: one | ||
uses libunwind directly, the other uses a libunwind-based | ||
implementation of the backtrace() function. The test program in | ||
src/tests/exc.c shows the basics of how to do exception handling with | ||
this library. | ||
|
||
The following steps should be used to compile and install this library: | ||
|
||
$ cd src | ||
$ make dep | ||
$ make | ||
$ make install prefix=PREFIX | ||
|
||
where PREFIX is the installation prefix. By default, a prefix of /usr | ||
is used, such that libunwind.a is installed in /usr/lib and unwind.h | ||
is installed in /usr/include. For testing, you may want to use a | ||
prefix of /usr/local instead. | ||
|
||
Please direct all questions regarding this library to: | ||
|
||
libunwind@linux.hpl.hp.com | ||
|
||
For spam protection, you'll have to subscribe to this list before | ||
posting a question. You can do this by sending a mail to | ||
libunwind-request@linux.hpl.hp.com with a body of: | ||
|
||
subscribe libunwind | ||
|
||
Note: the host that is running this list is behind a firewall, so | ||
you'll not be able to use the Web interface to manage your | ||
subscription. Send a mail containing "help" to | ||
libunwind-request@linux.hpl.hp.com for information on how to manage | ||
your subscription via email. | ||
|
||
--david |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
#undef SIGCONTEXT_HAS_AR25_AND_AR26 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
#define UNW_TARGET_IA64 | ||
#undef UNW_LOCAL_ONLY |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
/* libunwind - a platform-independent unwind library | ||
Copyright (C) 2001-2002 Hewlett-Packard Co | ||
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> | ||
This file is part of libunwind. | ||
libunwind is free software; you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation; either version 2, or (at your option) | ||
any later version. | ||
libunwind is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
You should have received a copy of the GNU General Public License | ||
along with GNU CC; see the file COPYING. If not, write to | ||
the Free Software Foundation, 59 Temple Place - Suite 330, | ||
Boston, MA 02111-1307, USA. | ||
As a special exception, if you link this library with other files to | ||
produce an executable, this library does not by itself cause the | ||
resulting executable to be covered by the GNU General Public License. | ||
This exception does not however invalidate any other reasons why the | ||
executable file might be covered by the GNU General Public | ||
License. */ | ||
|
||
#include <ucontext.h> | ||
|
||
typedef enum | ||
{ | ||
/* Note: general registers are excepted to start with index 0. | ||
This convention facilitates architecture-independent | ||
implementation of the C++ exception handling ABI. See | ||
_Unwind_SetGR() and _Unwind_GetGR() for details. */ | ||
UNW_IA64_GR = 0, /* general registers (r0..r127) */ | ||
UNW_IA64_GP = UNW_IA64_GR + 1, | ||
UNW_IA64_SP = UNW_IA64_GR + 12, | ||
UNW_IA64_TP = UNW_IA64_GR + 13, | ||
|
||
UNW_IA64_NAT = UNW_IA64_GR + 128, /* NaT registers (nat0..nat127) */ | ||
|
||
UNW_IA64_FR = UNW_IA64_NAT + 128, /* fp registers (f0..f127) */ | ||
|
||
UNW_IA64_AR = UNW_IA64_FR + 128, /* application registers (ar0..r127) */ | ||
UNW_IA64_AR_RSC = UNW_IA64_AR + 16, | ||
UNW_IA64_AR_BSP = UNW_IA64_AR + 17, | ||
UNW_IA64_AR_BSPSTORE = UNW_IA64_AR + 18, | ||
UNW_IA64_AR_RNAT = UNW_IA64_AR + 19, | ||
UNW_IA64_AR_25 = UNW_IA64_AR + 25, /* reserved (scratch) */ | ||
UNW_IA64_AR_26 = UNW_IA64_AR + 26, /* reserved (scratch) */ | ||
UNW_IA64_AR_CCV = UNW_IA64_AR + 32, | ||
UNW_IA64_AR_UNAT = UNW_IA64_AR + 36, | ||
UNW_IA64_AR_FPSR = UNW_IA64_AR + 40, | ||
UNW_IA64_AR_PFS = UNW_IA64_AR + 64, | ||
UNW_IA64_AR_LC = UNW_IA64_AR + 65, | ||
UNW_IA64_AR_EC = UNW_IA64_AR + 66, | ||
|
||
UNW_IA64_BR = UNW_IA64_AR + 128, /* branch registers (b0..p7) */ | ||
UNW_IA64_PR = UNW_IA64_BR + 8, /* predicate registers (p0..p63) */ | ||
UNW_IA64_CFM, | ||
|
||
/* frame info (read-only): */ | ||
UNW_IA64_CURRENT_BSP, /* read-only */ | ||
|
||
UNW_TDEP_LAST_REG = UNW_IA64_CURRENT_BSP | ||
} | ||
ia64_regnum_t; | ||
|
||
/* Info needed for a single IA-64 unwind. A pointer to this structure | ||
is expected in the acquire/release callbacks of the unwind | ||
accessors. */ | ||
typedef struct unw_ia64_table | ||
{ | ||
const char *name; /* table name (or NULL if none) */ | ||
unw_word_t gp; /* global pointer for this load-module */ | ||
unw_word_t segbase; /* base for offsets in the unwind table */ | ||
unw_word_t length; /* number of entries in unwind table array */ | ||
|
||
/* Local copy of the unwind descriptor table: */ | ||
const struct ia64_unwind_table_entry *array; | ||
|
||
/* Local copy of the unwind descriptor information. This is | ||
initialized such that adding the unwind entry's info_offset | ||
yields the address at which the corresponding descriptors can | ||
be found. */ | ||
const unsigned char *unwind_info_base; | ||
} | ||
unw_ia64_table_t; | ||
|
||
/* On IA-64, we can directly use ucontext_t as the unwind context. */ | ||
typedef ucontext_t unw_tdep_context_t; | ||
|
||
/* XXX this is not ideal: an application should not be prevented from | ||
using the "getcontext" name just because it's using libunwind. We | ||
can't just use __getcontext() either, because that isn't exported | ||
by glibc... */ | ||
#define unw_tdep_getcontext(uc) getcontext(uc) |
Oops, something went wrong.