Merge branch 'maint-0.4.5' into release-0.4.5
[tor.git] / m4 / pc_from_ucontext.m4
blob61d979622b443e17bbcb1827c6920c2ca667a636
1 # This file is from Google Performance Tools, svn revision r226.
3 # The Google Performance Tools license is:
4 ########
5 # Copyright (c) 2005, Google Inc.
6 # All rights reserved.
8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions are
10 # met:
12 #     * Redistributions of source code must retain the above copyright
13 # notice, this list of conditions and the following disclaimer.
14 #     * Redistributions in binary form must reproduce the above
15 # copyright notice, this list of conditions and the following disclaimer
16 # in the documentation and/or other materials provided with the
17 # distribution.
18 #     * Neither the name of Google Inc. nor the names of its
19 # contributors may be used to endorse or promote products derived from
20 # this software without specific prior written permission.
22 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 ########
34 # Original file follows below.
36 # We want to access the "PC" (Program Counter) register from a struct
37 # ucontext.  Every system has its own way of doing that.  We try all the
38 # possibilities we know about.  Note REG_PC should come first (REG_RIP
39 # is also defined on solaris, but does the wrong thing).
41 # OpenBSD doesn't have ucontext.h, but we can get PC from ucontext_t
42 # by using signal.h.
44 # The first argument of AC_PC_FROM_UCONTEXT will be invoked when we
45 # cannot find a way to obtain PC from ucontext.
47 AC_DEFUN([AC_PC_FROM_UCONTEXT],
48   [AC_CHECK_HEADERS(ucontext.h)
49    # Redhat 7 has <sys/ucontext.h>, but it barfs if we #include it directly
50    # (this was fixed in later redhats).  <ucontext.h> works fine, so use that.
51    if grep "Red Hat Linux release 7" /etc/redhat-release >/dev/null 2>&1; then
52      AC_DEFINE(HAVE_SYS_UCONTEXT_H, 0, [<sys/ucontext.h> is broken on redhat 7])
53      ac_cv_header_sys_ucontext_h=no
54    else
55      AC_CHECK_HEADERS(sys/ucontext.h)       # ucontext on OS X 10.6 (at least)
56    fi
57    AC_CHECK_HEADERS(cygwin/signal.h)        # ucontext on cygwin
58    AC_MSG_CHECKING([how to access the program counter from a struct ucontext])
59    pc_fields="           uc_mcontext.gregs[[REG_PC]]"  # Solaris x86 (32 + 64 bit)
60    pc_fields="$pc_fields uc_mcontext.gregs[[REG_EIP]]" # Linux (i386)
61    pc_fields="$pc_fields uc_mcontext.gregs[[REG_RIP]]" # Linux (x86_64)
62    pc_fields="$pc_fields uc_mcontext.sc_ip"            # Linux (ia64)
63    pc_fields="$pc_fields uc_mcontext.uc_regs->gregs[[PT_NIP]]" # Linux (ppc)
64    pc_fields="$pc_fields uc_mcontext.gregs[[R15]]"     # Linux (arm old [untested])
65    pc_fields="$pc_fields uc_mcontext.arm_pc"           # Linux (arm arch 5)
66    pc_fields="$pc_fields uc_mcontext.gp_regs[[PT_NIP]]"  # Suse SLES 11 (ppc64)
67    pc_fields="$pc_fields uc_mcontext.mc_eip"           # FreeBSD (i386)
68    pc_fields="$pc_fields uc_mcontext.mc_rip"           # FreeBSD (x86_64 [untested])
69    pc_fields="$pc_fields uc_mcontext.__gregs[[_REG_EIP]]"  # NetBSD (i386)
70    pc_fields="$pc_fields uc_mcontext.__gregs[[_REG_RIP]]"  # NetBSD (x86_64)
71    pc_fields="$pc_fields uc_mcontext->ss.eip"          # OS X (i386, <=10.4)
72    pc_fields="$pc_fields uc_mcontext->__ss.__eip"      # OS X (i386, >=10.5)
73    pc_fields="$pc_fields uc_mcontext->ss.rip"          # OS X (x86_64)
74    pc_fields="$pc_fields uc_mcontext->__ss.__rip"      # OS X (>=10.5 [untested])
75    pc_fields="$pc_fields uc_mcontext->ss.srr0"         # OS X (ppc, ppc64 [untested])
76    pc_fields="$pc_fields uc_mcontext->__ss.__srr0"     # OS X (>=10.5 [untested])
77    pc_field_found=false
78    for pc_field in $pc_fields; do
79      if ! $pc_field_found; then
80        # Prefer sys/ucontext.h to ucontext.h, for OS X's sake.
81        if test "x$ac_cv_header_cygwin_signal_h" = xyes; then
82          AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <cygwin/signal.h>]],
83                         [[ucontext_t u; return u.$pc_field == 0;]])],
84                         AC_DEFINE_UNQUOTED(PC_FROM_UCONTEXT, $pc_field,
85                                            How to access the PC from a struct ucontext)
86                         AC_MSG_RESULT([$pc_field])
87                         pc_field_found=true)
88        elif test "x$ac_cv_header_sys_ucontext_h" = xyes; then
89          AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/ucontext.h>]],
90                         [[ucontext_t u; return u.$pc_field == 0;]])],
91                         AC_DEFINE_UNQUOTED(PC_FROM_UCONTEXT, $pc_field,
92                                            How to access the PC from a struct ucontext)
93                         AC_MSG_RESULT([$pc_field])
94                         pc_field_found=true)
95        elif test "x$ac_cv_header_ucontext_h" = xyes; then
96          AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <ucontext.h>]],
97                         [[ucontext_t u; return u.$pc_field == 0;]])],
98                         AC_DEFINE_UNQUOTED(PC_FROM_UCONTEXT, $pc_field,
99                                            How to access the PC from a struct ucontext)
100                         AC_MSG_RESULT([$pc_field])
101                         pc_field_found=true)
102        else     # hope some standard header gives it to us
103          AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]],
104                         [[ucontext_t u; return u.$pc_field == 0;]])],
105                         AC_DEFINE_UNQUOTED(PC_FROM_UCONTEXT, $pc_field,
106                                            How to access the PC from a struct ucontext)
107                         AC_MSG_RESULT([$pc_field])
108                         pc_field_found=true)
109        fi
110      fi
111    done
112    if ! $pc_field_found; then
113      pc_fields="           sc_eip"  # OpenBSD (i386)
114      pc_fields="$pc_fields sc_rip"  # OpenBSD (x86_64)
115      for pc_field in $pc_fields; do
116        if ! $pc_field_found; then
117          AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <signal.h>]],
118                         [[ucontext_t u; return u.$pc_field == 0;]])],
119                         AC_DEFINE_UNQUOTED(PC_FROM_UCONTEXT, $pc_field,
120                                            How to access the PC from a struct ucontext)
121                         AC_MSG_RESULT([$pc_field])
122                         pc_field_found=true)
123        fi
124      done
125    fi
126    if ! $pc_field_found; then
127      [$1]
128    fi])