Back to index

plt-scheme  4.2.1
libunwind.h
Go to the documentation of this file.
00001 /* libunwind - a platform-independent unwind library
00002    Copyright (C) 2002-2004 Hewlett-Packard Co
00003        Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
00004 
00005 This file is part of libunwind.
00006 
00007 Permission is hereby granted, free of charge, to any person obtaining
00008 a copy of this software and associated documentation files (the
00009 "Software"), to deal in the Software without restriction, including
00010 without limitation the rights to use, copy, modify, merge, publish,
00011 distribute, sublicense, and/or sell copies of the Software, and to
00012 permit persons to whom the Software is furnished to do so, subject to
00013 the following conditions:
00014 
00015 The above copyright notice and this permission notice shall be
00016 included in all copies or substantial portions of the Software.
00017 
00018 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00019 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00020 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00021 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00022 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00023 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00024 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
00025 
00026 #ifndef LIBUNWIND_H
00027 #define LIBUNWIND_H
00028 
00029 #if defined(linux)
00030 # define LINUX
00031 #endif
00032 #if defined(i386)
00033 # define PLAIN_X86
00034 #endif
00035 
00036 #ifdef PLAIN_X86
00037 # define UNW_IP UNW_X86_EIP
00038 #else
00039 # define UNW_IP UNW_X86_64_RIP
00040 #endif
00041 
00042 #if defined(__cplusplus) || defined(c_plusplus)
00043 extern "C" {
00044 #endif
00045 
00046 #include <inttypes.h>
00047 #define _XOPEN_SOURCE /* needed for Mac OS X */
00048 #define __USE_GNU
00049 #include <ucontext.h>
00050 #undef __USE_GNU
00051 
00052   /* XXXXXXXXXXXXXXXXXXXX x86 Target XXXXXXXXXXXXXXXXXXXX */
00053 
00054 #ifdef PLAIN_X86
00055 
00056 #define UNW_TARGET   x86
00057 #define UNW_TARGET_X86      1
00058 
00059 /* This needs to be big enough to accommodate "struct cursor", while
00060    leaving some slack for future expansion.  Changing this value will
00061    require recompiling all users of this library.  Stack allocation is
00062    relatively cheap and unwind-state copying is relatively rare, so we
00063    want to err on making it rather too big than too small.  */
00064 #define UNW_TDEP_CURSOR_LEN 127
00065 
00066 typedef unsigned long unw_word_t;
00067 typedef long unw_sword_t;
00068 
00069 typedef long double unw_tdep_fpreg_t;
00070 
00071 typedef enum
00072   {
00073     /* Note: general registers are expected to start with index 0.
00074        This convention facilitates architecture-independent
00075        implementation of the C++ exception handling ABI.  See
00076        _Unwind_SetGR() and _Unwind_GetGR() for details.
00077 
00078        The described register usage convention is based on "System V
00079        Application Binary Interface, Intel386 Architecture Processor
00080        Supplement, Fourth Edition" at
00081 
00082          http://www.linuxbase.org/spec/refspecs/elf/abi386-4.pdf
00083 
00084        It would have been nice to use the same register numbering as
00085        DWARF, but that doesn't work because the libunwind requires
00086        that the exception argument registers be consecutive, which the
00087        wouldn't be with the DWARF numbering.  */
00088     UNW_X86_EAX,     /* scratch (exception argument 1) */
00089     UNW_X86_EDX,     /* scratch (exception argument 2) */
00090     UNW_X86_ECX,     /* scratch */
00091     UNW_X86_EBX,     /* preserved */
00092     UNW_X86_ESI,     /* preserved */
00093     UNW_X86_EDI,     /* preserved */
00094     UNW_X86_EBP,     /* (optional) frame-register */
00095     UNW_X86_ESP,     /* (optional) frame-register */
00096     UNW_X86_EIP,     /* frame-register */
00097     UNW_X86_EFLAGS,  /* scratch (except for "direction", which is fixed */
00098     UNW_X86_TRAPNO,  /* scratch */
00099 
00100     /* MMX/stacked-fp registers */
00101     UNW_X86_ST0,     /* fp return value */
00102     UNW_X86_ST1,     /* scratch */
00103     UNW_X86_ST2,     /* scratch */
00104     UNW_X86_ST3,     /* scratch */
00105     UNW_X86_ST4,     /* scratch */
00106     UNW_X86_ST5,     /* scratch */
00107     UNW_X86_ST6,     /* scratch */
00108     UNW_X86_ST7,     /* scratch */
00109 
00110     UNW_X86_FCW,     /* scratch */
00111     UNW_X86_FSW,     /* scratch */
00112     UNW_X86_FTW,     /* scratch */
00113     UNW_X86_FOP,     /* scratch */
00114     UNW_X86_FCS,     /* scratch */
00115     UNW_X86_FIP,     /* scratch */
00116     UNW_X86_FEA,     /* scratch */
00117     UNW_X86_FDS,     /* scratch */
00118 
00119     /* SSE registers */
00120     UNW_X86_XMM0_lo, /* scratch */
00121     UNW_X86_XMM0_hi, /* scratch */
00122     UNW_X86_XMM1_lo, /* scratch */
00123     UNW_X86_XMM1_hi, /* scratch */
00124     UNW_X86_XMM2_lo, /* scratch */
00125     UNW_X86_XMM2_hi, /* scratch */
00126     UNW_X86_XMM3_lo, /* scratch */
00127     UNW_X86_XMM3_hi, /* scratch */
00128     UNW_X86_XMM4_lo, /* scratch */
00129     UNW_X86_XMM4_hi, /* scratch */
00130     UNW_X86_XMM5_lo, /* scratch */
00131     UNW_X86_XMM5_hi, /* scratch */
00132     UNW_X86_XMM6_lo, /* scratch */
00133     UNW_X86_XMM6_hi, /* scratch */
00134     UNW_X86_XMM7_lo, /* scratch */
00135     UNW_X86_XMM7_hi, /* scratch */
00136 
00137     UNW_X86_MXCSR,   /* scratch */
00138 
00139     /* segment registers */
00140     UNW_X86_GS,             /* special */
00141     UNW_X86_FS,             /* special */
00142     UNW_X86_ES,             /* special */
00143     UNW_X86_DS,             /* special */
00144     UNW_X86_SS,             /* special */
00145     UNW_X86_CS,             /* special */
00146     UNW_X86_TSS,     /* special */
00147     UNW_X86_LDT,     /* special */
00148 
00149     /* frame info (read-only) */
00150     UNW_X86_CFA,
00151 
00152     UNW_TDEP_LAST_REG = UNW_X86_LDT,
00153 
00154     UNW_TDEP_IP = UNW_X86_EIP,
00155     UNW_TDEP_SP = UNW_X86_CFA,
00156     UNW_TDEP_EH = UNW_X86_EAX
00157   }
00158 x86_regnum_t;
00159 
00160 #endif
00161 
00162   /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
00163 
00164   /* XXXXXXXXXXXXXXXXXXXX x86_64 Target XXXXXXXXXXXXXXXXXXXX */
00165 
00166 #ifndef PLAIN_X86
00167 
00168 #define UNW_TARGET          x86_64
00169 #define UNW_TARGET_X86_64   1
00170 
00171 #define _U_TDEP_QP_TRUE     0      /* see libunwind-dynamic.h  */
00172 
00173 /* This needs to be big enough to accommodate "struct cursor", while
00174    leaving some slack for future expansion.  Changing this value will
00175    require recompiling all users of this library.  Stack allocation is
00176    relatively cheap and unwind-state copying is relatively rare, so we
00177    want to err on making it rather too big than too small.  */
00178 #define UNW_TDEP_CURSOR_LEN 127
00179 
00180 typedef uint64_t unw_word_t;
00181 typedef int64_t unw_sword_t;
00182 
00183 typedef long double unw_tdep_fpreg_t;
00184 
00185 typedef enum
00186   {
00187     UNW_X86_64_RAX,
00188     UNW_X86_64_RDX,
00189     UNW_X86_64_RCX,
00190     UNW_X86_64_RBX,
00191     UNW_X86_64_RSI,
00192     UNW_X86_64_RDI,
00193     UNW_X86_64_RBP,
00194     UNW_X86_64_RSP,
00195     UNW_X86_64_R8,
00196     UNW_X86_64_R9,
00197     UNW_X86_64_R10,
00198     UNW_X86_64_R11,
00199     UNW_X86_64_R12,
00200     UNW_X86_64_R13,
00201     UNW_X86_64_R14,
00202     UNW_X86_64_R15,
00203     UNW_X86_64_RIP,
00204 
00205     /* XXX Add other regs here */
00206 
00207     /* frame info (read-only) */
00208     UNW_X86_64_CFA,
00209 
00210     UNW_TDEP_LAST_REG = UNW_X86_64_RIP,
00211 
00212     UNW_TDEP_IP = UNW_X86_64_RIP,
00213     UNW_TDEP_SP = UNW_X86_64_RSP,
00214     UNW_TDEP_BP = UNW_X86_64_RBP,
00215     UNW_TDEP_EH = UNW_X86_64_RAX
00216   }
00217 x86_64_regnum_t;
00218 
00219 #endif
00220 
00221   /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
00222 
00223 #define UNW_TDEP_NUM_EH_REGS       2      /* eax and edx are exception args */
00224 
00225 typedef struct unw_tdep_save_loc
00226   {
00227     /* Additional target-dependent info on a save location.  */
00228   }
00229 unw_tdep_save_loc_t;
00230 
00231 /* On x86, we can directly use ucontext_t as the unwind context.  */
00232 typedef ucontext_t unw_tdep_context_t;
00233 
00234 /* XXX this is not ideal: an application should not be prevented from
00235    using the "getcontext" name just because it's using libunwind.  We
00236    can't just use __getcontext() either, because that isn't exported
00237    by glibc...  */
00238 #define unw_tdep_getcontext(uc)           (getcontext (uc), 0)
00239 
00240 
00241 typedef struct unw_dyn_remote_table_info
00242   {
00243     unw_word_t name_ptr;    /* addr. of table name (e.g., library name) */
00244     unw_word_t segbase;            /* segment base */
00245     unw_word_t table_len;   /* must be a multiple of sizeof(unw_word_t)! */
00246     unw_word_t table_data;
00247   }
00248 unw_dyn_remote_table_info_t;
00249 
00250 typedef struct unw_dyn_info
00251   {
00252     /* doubly-linked list of dyn-info structures: */
00253     struct unw_dyn_info *next;
00254     struct unw_dyn_info *prev;
00255     unw_word_t start_ip;    /* first IP covered by this entry */
00256     unw_word_t end_ip;             /* first IP NOT covered by this entry */
00257     unw_word_t gp;          /* global-pointer in effect for this entry */
00258     int32_t format;         /* real type: unw_dyn_info_format_t */
00259     int32_t pad;
00260     union
00261       {
00262        unw_dyn_remote_table_info_t rti;
00263       }
00264     u;
00265   }
00266 unw_dyn_info_t;
00267 
00268 #define UNW_INFO_FORMAT_TABLE 1
00269 #define UNW_INFO_FORMAT_REMOTE_TABLE 2
00270 
00271 typedef struct
00272   {
00273     /* no x86-specific auxiliary proc-info */
00274   }
00275 unw_tdep_proc_info_t;
00276 
00277 #define UNW_VERSION_MAJOR   0
00278 #define UNW_VERSION_MINOR   99
00279 #define UNW_VERSION_EXTRA   0
00280 
00281 #define UNW_VERSION_CODE(maj,min)  (((maj) << 16) | (min))
00282 #define UNW_VERSION  UNW_VERSION_CODE(UNW_VERSION_MAJOR, UNW_VERSION_MINOR)
00283 
00284 #define UNW_PASTE2(x,y)     x##y
00285 #define UNW_PASTE(x,y)      UNW_PASTE2(x,y)
00286 #define UNW_OBJ(fn)  UNW_PASTE(UNW_PREFIX, fn)
00287 #define UNW_ARCH_OBJ(fn) UNW_PASTE(UNW_PASTE(UNW_PASTE(_U,UNW_TARGET),_), fn)
00288 
00289 #define UW_NO_SYNC
00290 
00291 #include <sys/types.h>
00292 
00293 # define UNW_PREFIX  UNW_PASTE(UNW_PASTE(_UL,UNW_TARGET),_)
00294 
00295 /* Error codes.  The unwind routines return the *negated* values of
00296    these error codes on error and a non-negative value on success.  */
00297 typedef enum
00298   {
00299     UNW_ESUCCESS = 0,              /* no error */
00300     UNW_EUNSPEC,            /* unspecified (general) error */
00301     UNW_ENOMEM,                    /* out of memory */
00302     UNW_EBADREG,            /* bad register number */
00303     UNW_EREADONLYREG,              /* attempt to write read-only register */
00304     UNW_ESTOPUNWIND,        /* stop unwinding */
00305     UNW_EINVALIDIP,         /* invalid IP */
00306     UNW_EBADFRAME,          /* bad frame */
00307     UNW_EINVAL,                    /* unsupported operation or bad value */
00308     UNW_EBADVERSION,        /* unwind info has unsupported version */
00309     UNW_ENOINFO                    /* no unwind info found */
00310   }
00311 unw_error_t;
00312 
00313 /* The following enum defines the indices for a couple of
00314    (pseudo-)registers which have the same meaning across all
00315    platforms.  (RO) means read-only.  (RW) means read-write.  General
00316    registers (aka "integer registers") are expected to start with
00317    index 0.  The number of such registers is architecture-dependent.
00318    The remaining indices can be used as an architecture sees fit.  The
00319    last valid register index is given by UNW_REG_LAST.  */
00320 typedef enum
00321   {
00322     UNW_REG_IP = UNW_TDEP_IP,             /* (rw) instruction pointer (pc) */
00323     UNW_REG_SP = UNW_TDEP_SP,             /* (ro) stack pointer */
00324     UNW_REG_EH = UNW_TDEP_EH,             /* (rw) exception-handling reg base */
00325     UNW_REG_LAST = UNW_TDEP_LAST_REG
00326   }
00327 unw_frame_regnum_t;
00328 
00329 /* Number of exception-handler argument registers: */
00330 #define UNW_NUM_EH_REGS            UNW_TDEP_NUM_EH_REGS
00331 
00332 typedef enum
00333   {
00334     UNW_CACHE_NONE,                /* no caching */
00335     UNW_CACHE_GLOBAL,                     /* shared global cache */
00336     UNW_CACHE_PER_THREAD           /* per-thread caching */
00337   }
00338 unw_caching_policy_t;
00339 
00340 typedef int unw_regnum_t;
00341 
00342 /* The unwind cursor starts at the youngest (most deeply nested) frame
00343    and is used to track the frame state as the unwinder steps from
00344    frame to frame.  It is safe to make (shallow) copies of variables
00345    of this type.  */
00346 typedef struct unw_cursor
00347   {
00348     unw_word_t opaque[UNW_TDEP_CURSOR_LEN];
00349   }
00350 unw_cursor_t;
00351 
00352 /* This type encapsulates the entire (preserved) machine-state.  */
00353 typedef unw_tdep_context_t unw_context_t;
00354 
00355 /* unw_getcontext() fills the unw_context_t pointed to by UC with the
00356    machine state as it exists at the call-site.  For implementation
00357    reasons, this needs to be a target-dependent macro.  It's easiest
00358    to think of unw_getcontext() as being identical to getcontext(). */
00359 #define unw_getcontext(uc)         unw_tdep_getcontext(uc)
00360 
00361 /* Return 1 if register number R is a floating-point register, zero
00362    otherwise.
00363    This routine is signal-safe.  */
00364 #define unw_is_fpreg(r)                   unw_tdep_is_fpreg(r)
00365 
00366 typedef unw_tdep_fpreg_t unw_fpreg_t;
00367 
00368 typedef struct unw_addr_space *unw_addr_space_t;
00369 
00370 /* Each target may define it's own set of flags, but bits 0-15 are
00371    reserved for general libunwind-use.  */
00372 #define UNW_PI_FLAG_FIRST_TDEP_BIT 16
00373 
00374 typedef struct unw_proc_info
00375   {
00376     unw_word_t start_ip;    /* first IP covered by this procedure */
00377     unw_word_t end_ip;             /* first IP NOT covered by this procedure */
00378     unw_word_t lsda;        /* address of lang.-spec. data area (if any) */
00379     unw_word_t handler;            /* optional personality routine */
00380     unw_word_t gp;          /* global-pointer value for this procedure */
00381     unw_word_t flags;              /* misc. flags */
00382 
00383     int format;                    /* unwind-info format (arch-specific) */
00384     int unwind_info_size;   /* size of the information (if applicable) */
00385     void *unwind_info;             /* unwind-info (arch-specific) */
00386     unw_tdep_proc_info_t extra;    /* target-dependent auxiliary proc-info */
00387   }
00388 unw_proc_info_t;
00389 
00390 /* These are backend callback routines that provide access to the
00391    state of a "remote" process.  This can be used, for example, to
00392    unwind another process through the ptrace() interface.  */
00393 typedef struct unw_accessors
00394   {
00395     /* REMOVED */
00396   }
00397 unw_accessors_t;
00398 
00399 typedef enum unw_save_loc_type
00400   {
00401     UNW_SLT_NONE,    /* register is not saved ("not an l-value") */
00402     UNW_SLT_MEMORY,  /* register has been saved in memory */
00403     UNW_SLT_REG             /* register has been saved in (another) register */
00404   }
00405 unw_save_loc_type_t;
00406 
00407 typedef struct unw_save_loc
00408   {
00409     unw_save_loc_type_t type;
00410     union
00411       {
00412        unw_word_t addr;     /* valid if type==UNW_SLT_MEMORY */
00413        unw_regnum_t regnum; /* valid if type==UNW_SLT_REG */
00414       }
00415     u;
00416     unw_tdep_save_loc_t extra;     /* target-dependent additional information */
00417   }
00418 unw_save_loc_t;
00419 
00420 /* These routines work both for local and remote unwinding.  */
00421 
00422 #define unw_local_addr_space       UNW_OBJ(local_addr_space)
00423 #define unw_create_addr_space      UNW_OBJ(create_addr_space)
00424 #define unw_destroy_addr_space     UNW_OBJ(destroy_addr_space)
00425 #define unw_get_accessors   UNW_ARCH_OBJ(get_accessors)
00426 #define unw_init_local             UNW_OBJ(init_local)
00427 #define unw_init_remote            UNW_OBJ(init_remote)
00428 #define unw_step            UNW_OBJ(step)
00429 #define unw_resume          UNW_OBJ(resume)
00430 #define unw_get_proc_info   UNW_OBJ(get_proc_info)
00431 #define unw_get_proc_info_by_ip    UNW_OBJ(get_proc_info_by_ip)
00432 #define unw_get_reg         UNW_OBJ(get_reg)
00433 #define unw_set_reg         UNW_OBJ(set_reg)
00434 #define unw_get_fpreg              UNW_OBJ(get_fpreg)
00435 #define unw_set_fpreg              UNW_OBJ(set_fpreg)
00436 #define unw_get_save_loc    UNW_OBJ(get_save_loc)
00437 #define unw_is_signal_frame UNW_OBJ(is_signal_frame)
00438 #define unw_get_proc_name   UNW_OBJ(get_proc_name)
00439 #define unw_set_caching_policy     UNW_OBJ(set_caching_policy)
00440 #define unw_regname         UNW_ARCH_OBJ(regname)
00441 #define unw_flush_cache            UNW_ARCH_OBJ(flush_cache)
00442 #define unw_strerror        UNW_ARCH_OBJ(strerror)
00443 
00444 extern unw_addr_space_t unw_create_addr_space (unw_accessors_t *, int);
00445 extern void unw_destroy_addr_space (unw_addr_space_t);
00446 extern unw_accessors_t *unw_get_accessors (unw_addr_space_t);
00447 extern void unw_flush_cache (unw_addr_space_t, unw_word_t, unw_word_t);
00448 extern int unw_set_caching_policy (unw_addr_space_t, unw_caching_policy_t);
00449 extern const char *unw_regname (unw_regnum_t);
00450 
00451 extern int unw_init_local (unw_cursor_t *, unw_context_t *);
00452 extern int unw_init_remote (unw_cursor_t *, unw_addr_space_t, void *);
00453 extern int unw_step (unw_cursor_t *);
00454 extern int unw_resume (unw_cursor_t *);
00455 extern int unw_get_proc_info (unw_cursor_t *, unw_proc_info_t *);
00456 extern int unw_get_proc_info_by_ip (unw_addr_space_t, unw_word_t,
00457                                 unw_proc_info_t *, void *);
00458 extern int unw_get_reg (unw_cursor_t *, int, unw_word_t *);
00459 extern int unw_set_reg (unw_cursor_t *, int, unw_word_t);
00460 extern int unw_get_fpreg (unw_cursor_t *, int, unw_fpreg_t *);
00461 extern int unw_set_fpreg (unw_cursor_t *, int, unw_fpreg_t);
00462 extern int unw_get_save_loc (unw_cursor_t *, int, unw_save_loc_t *);
00463 extern int unw_is_signal_frame (unw_cursor_t *);
00464 extern int unw_get_proc_name (unw_cursor_t *, char *, size_t, unw_word_t *);
00465 extern unw_word_t unw_get_ip(unw_cursor_t *);
00466 extern unw_word_t unw_get_frame_pointer(unw_cursor_t *);
00467 extern const char *unw_strerror (int);
00468 
00469 void unw_manual_step(unw_cursor_t *_c, 
00470                    void *ip_addr,
00471                    void *bp_addr,
00472                    void *sp_addr,
00473                    void *bx_addr,
00474                    void *r12_addr,
00475                    void *r13_addr);
00476   
00477 extern unw_addr_space_t unw_local_addr_space;
00478 
00479 extern int unw_reset_bad_ptr_flag();
00480 extern void unw_set_safe_pointer_range(unw_word_t s, unw_word_t e);
00481 
00482 #define unw_tdep_is_fpreg          UNW_ARCH_OBJ(is_fpreg)
00483 extern int unw_tdep_is_fpreg (int);
00484 
00485 #if defined(__cplusplus) || defined(c_plusplus)
00486 }
00487 #endif
00488 
00489 #endif /* LIBUNWIND_H */