1#
2# Contains macros to detect OS features.
3#
4
5
6# DRUNTIME_OS_THREAD_MODEL
7# ------------------------
8# Detect thread model and substitute DCFG_THREAD_MODEL
9AC_DEFUN([DRUNTIME_OS_THREAD_MODEL],
10[
11  AC_REQUIRE([AC_PROG_GDC])
12  AC_MSG_CHECKING([for thread model used by GDC])
13  d_thread_model=`$GDC -v 2>&1 | sed -n 's/^Thread model: //p'`
14  AC_MSG_RESULT([$d_thread_model])
15
16  # Map from thread model to thread interface.
17  DRUNTIME_CONFIGURE_THREADS([$d_thread_model])
18])
19
20
21# DRUNTIME_CONFIGURE_THREADS(thread_model)
22# ----------------------------------------
23# Map target os to D version identifier
24AC_DEFUN([DRUNTIME_CONFIGURE_THREADS],
25[
26case $1 in
27    aix)    DCFG_THREAD_MODEL="Posix" ;;
28    lynx)   DCFG_THREAD_MODEL="Posix" ;;
29    posix)  DCFG_THREAD_MODEL="Posix" ;;
30    single) DCFG_THREAD_MODEL="Single" ;;
31    win32)  DCFG_THREAD_MODEL="Win32" ;;
32    # TODO: These targets need porting.
33    dce|mipssde|rtems|tpf|vxworks)
34	    DCFG_THREAD_MODEL="Single" ;;
35    *)	    as_fn_error "Thread implementation '$1' not recognised" "$LINENO" 5 ;;
36esac
37AC_SUBST(DCFG_THREAD_MODEL)
38])
39
40
41# DRUNTIME_OS_DETECT
42# ------------------
43# Set the druntime_cv_target_os variable
44AC_DEFUN([DRUNTIME_OS_DETECT],
45[
46  AC_CACHE_CHECK([[for target OS]],
47    [[druntime_cv_target_os]],
48    [[druntime_cv_target_os=`echo $target_os | sed 's/^\([A-Za-z_]+\)/\1/'`]])
49    AS_IF([[test -z "$druntime_cv_target_os"]],
50      [AC_MSG_ERROR([[can't detect target OS]])],
51      [])
52])
53
54
55# DRUNTIME_OS_SOURCES
56# -------------------
57# Detect target OS and add DRUNTIME_OS_AIX DRUNTIME_OS_ANDROID
58# DRUNTIME_OS_DARWIN DRUNTIME_OS_DRAGONFLYBSD DRUNTIME_OS_FREEBSD
59# DRUNTIME_OS_LINUX DRUNTIME_OS_MINGW DRUNTIME_OS_NETBSD
60# DRUNTIME_OS_OPENBSD DRUNTIME_OS_SOLARIS conditionals.
61# If the system is posix, add DRUNTIME_OS_POSIX conditional.
62AC_DEFUN([DRUNTIME_OS_SOURCES],
63[
64  AC_REQUIRE([DRUNTIME_OS_DETECT])
65
66  druntime_target_os_parsed=""
67  case "$druntime_cv_target_os" in
68      aix*)    druntime_target_os_parsed="aix"
69               ;;
70      *android*)
71               druntime_target_os_parsed="android"
72               ;;
73      darwin*) druntime_target_os_parsed="darwin"
74               ;;
75      dragonfly*)
76               druntime_target_os_parsed="dragonflybsd"
77               ;;
78      freebsd*|k*bsd*-gnu)
79               druntime_target_os_parsed="freebsd"
80               ;;
81      openbsd*)
82               druntime_target_os_parsed="openbsd"
83               ;;
84      netbsd*)
85               druntime_target_os_parsed="netbsd"
86               ;;
87      linux*)  druntime_target_os_parsed="linux"
88               ;;
89      mingw*)  druntime_target_os_parsed="mingw"
90             ;;
91      *solaris*) druntime_target_os_parsed="solaris"
92  esac
93  AM_CONDITIONAL([DRUNTIME_OS_AIX],
94                 [test "$druntime_target_os_parsed" = "aix"])
95  AM_CONDITIONAL([DRUNTIME_OS_ANDROID],
96                 [test "$druntime_target_os_parsed" = "android"])
97  AM_CONDITIONAL([DRUNTIME_OS_DARWIN],
98                 [test "$druntime_target_os_parsed" = "darwin"])
99  AM_CONDITIONAL([DRUNTIME_OS_DRAGONFLYBSD],
100                 [test "$druntime_target_os_parsed" = "dragonflybsd"])
101  AM_CONDITIONAL([DRUNTIME_OS_FREEBSD],
102                 [test "$druntime_target_os_parsed" = "freebsd"])
103  AM_CONDITIONAL([DRUNTIME_OS_NETBSD],
104                 [test "$druntime_target_os_parsed" = "netbsd"])
105  AM_CONDITIONAL([DRUNTIME_OS_OPENBSD],
106                 [test "$druntime_target_os_parsed" = "openbsd"])
107  AM_CONDITIONAL([DRUNTIME_OS_LINUX],
108                 [test "$druntime_target_os_parsed" = "linux"])
109  AM_CONDITIONAL([DRUNTIME_OS_MINGW],
110                 [test "$druntime_target_os_parsed" = "mingw"])
111  AM_CONDITIONAL([DRUNTIME_OS_SOLARIS],
112                 [test "$druntime_target_os_parsed" = "solaris"])
113
114  druntime_target_posix="no"
115  case "$druntime_cv_target_os" in
116    aix*|*bsd*|cygwin*|darwin*|dragonfly*|gnu*|linux*|skyos*|*solaris*|sysv*)
117      druntime_target_posix="yes"
118      ;;
119  esac
120  AM_CONDITIONAL([DRUNTIME_OS_POSIX], [test "$druntime_target_posix" = "yes"])
121])
122
123
124# DRUNTIME_OS_ARM_EABI_UNWINDER
125# ------------------------
126# Check if using ARM unwinder and substitute DCFG_ARM_EABI_UNWINDER
127# and set DRUNTIME_OS_ARM_EABI_UNWINDER conditional.
128AC_DEFUN([DRUNTIME_OS_ARM_EABI_UNWINDER],
129[
130  AC_LANG_PUSH([C])
131  AC_MSG_CHECKING([for ARM unwinder])
132  AC_TRY_COMPILE([#include <unwind.h>],[
133  #if __ARM_EABI_UNWINDER__
134  #error Yes, it is.
135  #endif
136  ],
137    [AC_MSG_RESULT([no])
138     DCFG_ARM_EABI_UNWINDER=false],
139    [AC_MSG_RESULT([yes])
140     DCFG_ARM_EABI_UNWINDER=true])
141  AC_SUBST(DCFG_ARM_EABI_UNWINDER)
142  AM_CONDITIONAL([DRUNTIME_OS_ARM_EABI_UNWINDER], [test "$DCFG_ARM_EABI_UNWINDER" = "true"])
143  AC_LANG_POP([C])
144])
145
146
147# DRUNTIME_OS_MINFO_BRACKETING
148# ----------------------------
149# Check if the linker provides __start_minfo and __stop_minfo symbols and
150# substitute DCFG_MINFO_BRACKETING.
151AC_DEFUN([DRUNTIME_OS_MINFO_BRACKETING],
152[
153  AC_REQUIRE([DRUNTIME_OS_DETECT])
154
155  AC_LANG_PUSH([C])
156  AC_MSG_CHECKING([for minfo section bracketing])
157  case "$druntime_cv_target_os" in
158      darwin*)
159	section="__DATA,__minfodata"
160	start="section\$start\$__DATA\$__minfodata"
161	stop="section\$end\$__DATA\$__minfodata"
162	;;
163      *)
164	section="minfo"
165	start="__start_minfo"
166	stop="__stop_minfo"
167	;;
168  esac
169  AC_LINK_IFELSE([AC_LANG_SOURCE([
170    void* module_info_ptr __attribute__((section ("$section")));
171    extern void* start_minfo __asm__("$start") __attribute__((visibility ("hidden")));
172    extern void* stop_minfo __asm__("$stop") __attribute__((visibility ("hidden")));
173
174    int main()
175    {
176        // Never run, just to prevent compiler from optimizing access
177        return (int)(&stop_minfo - &start_minfo);
178    }
179  ])],
180    [AC_MSG_RESULT([yes])
181     DCFG_MINFO_BRACKETING=true],
182    [AC_MSG_RESULT([no])
183     DCFG_MINFO_BRACKETING=false])
184  AC_SUBST(DCFG_MINFO_BRACKETING)
185  AM_CONDITIONAL([DRUNTIME_OS_MINFO_BRACKETING], [test "$DCFG_MINFO_BRACKETING" = "true"])
186  AC_LANG_POP([C])
187])
188
189# DRUNTIME_OS_DLPI_TLS_MODID
190# ----------------------------
191# Check if struct dl_phdr_info includes the dlpi_tls_modid member and  
192# substitute DCFG_DLPI_TLS_MODID.
193AC_DEFUN([DRUNTIME_OS_DLPI_TLS_MODID],
194[
195  AC_LANG_PUSH([C])
196  AC_CHECK_MEMBER([struct dl_phdr_info.dlpi_tls_modid],
197		  [DCFG_DLPI_TLS_MODID=true], [DCFG_DLPI_TLS_MODID=false],
198		  [[#include <link.h>]])
199  AC_SUBST(DCFG_DLPI_TLS_MODID)
200  AC_LANG_POP([C])
201])
202
203# DRUNTIME_OS_LINK_SPEC
204# ---------------------
205# Add target-specific link options to link_spec.
206AC_DEFUN([DRUNTIME_OS_LINK_SPEC],
207[
208  case $target in
209    i?86-*-solaris2.* | x86_64-*-solaris2.*)
210      # 64-bit Solaris/x86 ld breaks calls to __tls_get_addr with non-TLS
211      # relocs.  Work around by disabling TLS transitions.  Not necessary
212      # on 32-bit x86, but cannot be distinguished reliably in specs.
213      druntime_ld_prog=`$CC -print-prog-name=ld`
214      druntime_ld_gld=no
215      druntime_ld_relax_transtls=no
216      if test -n "$druntime_ld_prog" \
217         && $druntime_ld_prog -v 2>&1 | grep GNU > /dev/null 2>&1; then
218        druntime_ld_gld=yes
219      else
220        echo 'int main (void) { return 0; }' > conftest.c
221        save_LDFLAGS="$LDFLAGS"
222        LDFLAGS="$LDFLAGS -Wl,-z,relax=transtls"
223        if $CC $CFLAGS $LDFLAGS -o conftest conftest.c > /dev/null 2>&1; then
224          druntime_ld_relax_transtls=yes
225        fi
226        LDFLAGS="$save_LDFLAGS"
227        rm -f conftest.c conftest
228      fi
229      if test "$druntime_ld_relax_transtls" = "yes"; then
230        OS_LINK_SPEC='-z relax=transtls'
231      fi
232      ;;
233  esac
234  AC_SUBST(OS_LINK_SPEC)
235])
236