diff options
Diffstat (limited to 'ports/sysdeps/unix')
-rw-r--r-- | ports/sysdeps/unix/sysv/linux/mips/Makefile | 90 | ||||
-rw-r--r-- | ports/sysdeps/unix/sysv/linux/mips/configure | 171 | ||||
-rw-r--r-- | ports/sysdeps/unix/sysv/linux/mips/configure.in | 23 | ||||
-rw-r--r-- | ports/sysdeps/unix/sysv/linux/mips/dl-cache.h | 26 | ||||
-rw-r--r-- | ports/sysdeps/unix/sysv/linux/mips/readelflib.c | 35 |
5 files changed, 316 insertions, 29 deletions
diff --git a/ports/sysdeps/unix/sysv/linux/mips/Makefile b/ports/sysdeps/unix/sysv/linux/mips/Makefile index 1e54036bfe..9070b775c4 100644 --- a/ports/sysdeps/unix/sysv/linux/mips/Makefile +++ b/ports/sysdeps/unix/sysv/linux/mips/Makefile @@ -8,7 +8,9 @@ sysdep_routines += cachectl cacheflush sysmips _test_and_set sysdep_headers += sys/cachectl.h sys/sysmips.h sys/tas.h endif -abi-variants := o32_soft o32_hard n32_soft n32_hard n64_soft n64_hard +abi-variants := o32_soft o32_hard o32_soft_2008 o32_hard_2008 +abi-variants += n32_soft n32_hard n32_soft_2008 n32_hard_2008 +abi-variants += n64_soft n64_hard n64_soft_2008 n64_hard_2008 ifeq (,$(filter $(default-abi),$(abi-variants))) Unknown ABI, must be one of $(abi-variants) @@ -18,29 +20,89 @@ abi-includes := sgidefs.h # _MIPS_SIM_ABI32 == 1, _MIPS_SIM_NABI32 == 2, _MIPS_SIM_ABI64 == 3 abi-o32_soft-options := -U_MIPS_SIM -D_MIPS_SIM=1 \ - -D__mips_soft_float -U__mips_hard_float -abi-o32_soft-condition := defined(__mips_soft_float) \ - && (_MIPS_SIM == _MIPS_SIM_ABI32) + -D__mips_soft_float -U__mips_hard_float \ + -U__mips_nan2008 +abi-o32_soft-condition := !defined(__mips_nan2008) \ + && defined(__mips_soft_float) \ + && (_MIPS_SIM == _MIPS_SIM_ABI32) +abi-o32_soft-ld-soname := ld.so.1 abi-o32_hard-options := -U_MIPS_SIM -D_MIPS_SIM=1 \ - -D__mips_hard_float -U__mips_soft_float -abi-o32_hard-condition := defined(__mips_hard_float) \ + -D__mips_hard_float -U__mips_soft_float \ + -U__mips_nan2008 +abi-o32_hard-condition := !defined(__mips_nan2008) \ + && defined(__mips_hard_float) \ && (_MIPS_SIM == _MIPS_SIM_ABI32) +abi-o32_hard-ld-soname := ld.so.1 +abi-o32_soft_2008-options := -U_MIPS_SIM -D_MIPS_SIM=1 \ + -D__mips_soft_float -U__mips_hard_float \ + -D__mips_nan2008 +abi-o32_soft_2008-condition := defined(__mips_nan2008) \ + && defined(__mips_soft_float) \ + && (_MIPS_SIM == _MIPS_SIM_ABI32) +abi-o32_soft_2008-ld-soname := ld-linux-mipsn8.so.1 +abi-o32_hard_2008-options := -U_MIPS_SIM -D_MIPS_SIM=1 \ + -D__mips_hard_float -U__mips_soft_float \ + -D__mips_nan2008 +abi-o32_hard_2008-condition := defined(__mips_nan2008) \ + && defined(__mips_hard_float) \ + && (_MIPS_SIM == _MIPS_SIM_ABI32) +abi-o32_hard_2008-ld-soname := ld-linux-mipsn8.so.1 abi-n32_soft-options := -U_MIPS_SIM -D_MIPS_SIM=2 \ - -D__mips_soft_float -U__mips_hard_float -abi-n32_soft-condition := defined(__mips_soft_float) \ + -D__mips_soft_float -U__mips_hard_float \ + -U__mips_nan2008 +abi-n32_soft-condition := !defined(__mips_nan2008) \ + && defined(__mips_soft_float) \ && (_MIPS_SIM == _MIPS_SIM_NABI32) +abi-n32_soft-ld-soname := ld.so.1 abi-n32_hard-options := -U_MIPS_SIM -D_MIPS_SIM=2 \ - -D__mips_hard_float -U__mips_soft_float -abi-n32_hard-condition := defined(__mips_hard_float) \ + -D__mips_hard_float -U__mips_soft_float \ + -U__mips_nan2008 +abi-n32_hard-condition := !defined(__mips_nan2008) \ + && defined(__mips_hard_float) \ && (_MIPS_SIM == _MIPS_SIM_NABI32) +abi-n32_hard-ld-soname := ld.so.1 +abi-n32_soft_2008-options := -U_MIPS_SIM -D_MIPS_SIM=2 \ + -D__mips_soft_float -U__mips_hard_float \ + -D__mips_nan2008 +abi-n32_soft_2008-condition := defined(__mips_nan2008) \ + && defined(__mips_soft_float) \ + && (_MIPS_SIM == _MIPS_SIM_NABI32) +abi-n32_soft_2008-ld-soname := ld-linux-mipsn8.so.1 +abi-n32_hard_2008-options := -U_MIPS_SIM -D_MIPS_SIM=2 \ + -D__mips_hard_float -U__mips_soft_float \ + -D__mips_nan2008 +abi-n32_hard_2008-condition := defined(__mips_nan2008) \ + && defined(__mips_hard_float) \ + && (_MIPS_SIM == _MIPS_SIM_NABI32) +abi-n32_hard_2008-ld-soname := ld-linux-mipsn8.so.1 abi-n64_soft-options := -U_MIPS_SIM -D_MIPS_SIM=3 \ - -D__mips_soft_float -U__mips_hard_float -abi-n64_soft-condition := defined(__mips_soft_float) \ + -D__mips_soft_float -U__mips_hard_float \ + -U__mips_nan2008 +abi-n64_soft-condition := !defined(__mips_nan2008) \ + && defined(__mips_soft_float) \ && (_MIPS_SIM == _MIPS_SIM_ABI64) +abi-n64_soft-ld-soname := ld.so.1 abi-n64_hard-options := -U_MIPS_SIM -D_MIPS_SIM=3 \ - -D__mips_hard_float -U__mips_soft_float -abi-n64_hard-condition := defined(__mips_hard_float) \ + -D__mips_hard_float -U__mips_soft_float \ + -U__mips_nan2008 +abi-n64_hard-condition := !defined(__mips_nan2008) \ + && defined(__mips_hard_float) \ && (_MIPS_SIM == _MIPS_SIM_ABI64) +abi-n64_hard-ld-soname := ld.so.1 +abi-n64_soft_2008-options := -U_MIPS_SIM -D_MIPS_SIM=3 \ + -D__mips_soft_float -U__mips_hard_float \ + -D__mips_nan2008 +abi-n64_soft_2008-condition := defined(__mips_nan2008) \ + && defined(__mips_soft_float) \ + && (_MIPS_SIM == _MIPS_SIM_ABI64) +abi-n64_soft_2008-ld-soname := ld-linux-mipsn8.so.1 +abi-n64_hard_2008-options := -U_MIPS_SIM -D_MIPS_SIM=3 \ + -D__mips_hard_float -U__mips_soft_float \ + -D__mips_nan2008 +abi-n64_hard_2008-condition := defined(__mips_nan2008) \ + && defined(__mips_hard_float) \ + && (_MIPS_SIM == _MIPS_SIM_ABI64) +abi-n64_hard_2008-ld-soname := ld-linux-mipsn8.so.1 ifeq ($(subdir),elf) ifeq ($(build-shared),yes) diff --git a/ports/sysdeps/unix/sysv/linux/mips/configure b/ports/sysdeps/unix/sysv/linux/mips/configure index b4ee83e3ae..088210ff97 100644 --- a/ports/sysdeps/unix/sysv/linux/mips/configure +++ b/ports/sysdeps/unix/sysv/linux/mips/configure @@ -105,8 +105,168 @@ if test -z "$libc_mips_float"; then as_fn_error $? "could not determine if compiler is using hard or soft floating point ABI" "$LINENO" 5 fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler is using the 2008 NaN encoding" >&5 +$as_echo_n "checking whether the compiler is using the 2008 NaN encoding... " >&6; } +if ${libc_cv_mips_nan2008+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +dnl +#ifdef __mips_nan2008 +yes +#endif +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "yes" >/dev/null 2>&1; then : + libc_cv_mips_nan2008=yes +else + libc_cv_mips_nan2008=no +fi +rm -f conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_mips_nan2008" >&5 +$as_echo "$libc_cv_mips_nan2008" >&6; } + +libc_mips_nan= +if test x"$libc_cv_mips_nan2008" = xyes; then + libc_mips_nan=_2008 +fi + config_vars="$config_vars -default-abi = ${libc_mips_abi}_${libc_mips_float}" +default-abi = ${libc_mips_abi}_${libc_mips_float}${libc_mips_nan}" case "$prefix" in /usr | /usr/) @@ -138,3 +298,12 @@ case "$prefix" in esac libc_cv_gcc_unwind_find_fde=yes + +if test -z "$arch_minimum_kernel"; then + if test x$libc_cv_mips_nan2008 = xyes; then + # FIXME: Adjust this setting to the actual first upstream kernel + # version to support the 2008 NaN encoding and then remove this + # comment. + arch_minimum_kernel=10.0.0 + fi +fi diff --git a/ports/sysdeps/unix/sysv/linux/mips/configure.in b/ports/sysdeps/unix/sysv/linux/mips/configure.in index b8dde6ef7a..7087a14a5e 100644 --- a/ports/sysdeps/unix/sysv/linux/mips/configure.in +++ b/ports/sysdeps/unix/sysv/linux/mips/configure.in @@ -44,7 +44,19 @@ if test -z "$libc_mips_float"; then AC_MSG_ERROR([could not determine if compiler is using hard or soft floating point ABI]) fi -LIBC_CONFIG_VAR([default-abi], [${libc_mips_abi}_${libc_mips_float}]) +AC_CACHE_CHECK([whether the compiler is using the 2008 NaN encoding], + libc_cv_mips_nan2008, [AC_EGREP_CPP(yes, [dnl +#ifdef __mips_nan2008 +yes +#endif], libc_cv_mips_nan2008=yes, libc_cv_mips_nan2008=no)]) + +libc_mips_nan= +if test x"$libc_cv_mips_nan2008" = xyes; then + libc_mips_nan=_2008 +fi + +LIBC_CONFIG_VAR([default-abi], + [${libc_mips_abi}_${libc_mips_float}${libc_mips_nan}]) case "$prefix" in /usr | /usr/) @@ -76,3 +88,12 @@ case "$prefix" in esac libc_cv_gcc_unwind_find_fde=yes + +if test -z "$arch_minimum_kernel"; then + if test x$libc_cv_mips_nan2008 = xyes; then + # FIXME: Adjust this setting to the actual first upstream kernel + # version to support the 2008 NaN encoding and then remove this + # comment. + arch_minimum_kernel=10.0.0 + fi +fi diff --git a/ports/sysdeps/unix/sysv/linux/mips/dl-cache.h b/ports/sysdeps/unix/sysv/linux/mips/dl-cache.h index 4a7f3f1f2a..49ad99ab92 100644 --- a/ports/sysdeps/unix/sysv/linux/mips/dl-cache.h +++ b/ports/sysdeps/unix/sysv/linux/mips/dl-cache.h @@ -18,11 +18,27 @@ #include <ldconfig.h> -/* Redefine the cache ID for new ABIs; o32 keeps using the generic check. */ -#if _MIPS_SIM == _ABI64 -# define _DL_CACHE_DEFAULT_ID (FLAG_MIPS64_LIBN64 | FLAG_ELF_LIBC6) -#elif _MIPS_SIM == _ABIN32 -# define _DL_CACHE_DEFAULT_ID (FLAG_MIPS64_LIBN32 | FLAG_ELF_LIBC6) +#if ((defined __mips_nan2008 && !defined HAVE_MIPS_NAN2008) \ + || (!defined __mips_nan2008 && defined HAVE_MIPS_NAN2008)) +# error "Configuration inconsistency: __mips_nan2008 != HAVE_MIPS_NAN2008, overridden CFLAGS?" +#endif + +/* Redefine the cache ID for new ABIs and 2008 NaN support; legacy o32 + keeps using the generic check. */ +#ifdef __mips_nan2008 +# if _MIPS_SIM == _ABIO32 +# define _DL_CACHE_DEFAULT_ID (FLAG_MIPS_LIB32_NAN2008 | FLAG_ELF_LIBC6) +# elif _MIPS_SIM == _ABI64 +# define _DL_CACHE_DEFAULT_ID (FLAG_MIPS64_LIBN64_NAN2008 | FLAG_ELF_LIBC6) +# elif _MIPS_SIM == _ABIN32 +# define _DL_CACHE_DEFAULT_ID (FLAG_MIPS64_LIBN32_NAN2008 | FLAG_ELF_LIBC6) +# endif +#else +# if _MIPS_SIM == _ABI64 +# define _DL_CACHE_DEFAULT_ID (FLAG_MIPS64_LIBN64 | FLAG_ELF_LIBC6) +# elif _MIPS_SIM == _ABIN32 +# define _DL_CACHE_DEFAULT_ID (FLAG_MIPS64_LIBN32 | FLAG_ELF_LIBC6) +# endif #endif #ifdef _DL_CACHE_DEFAULT_ID diff --git a/ports/sysdeps/unix/sysv/linux/mips/readelflib.c b/ports/sysdeps/unix/sysv/linux/mips/readelflib.c index 10f0ff7022..fd57a735c3 100644 --- a/ports/sysdeps/unix/sysv/linux/mips/readelflib.c +++ b/ports/sysdeps/unix/sysv/linux/mips/readelflib.c @@ -33,19 +33,32 @@ process_elf_file (const char *file_name, const char *lib, int *flag, unsigned int *osversion, char **soname, void *file_contents, size_t file_length) { - ElfW(Ehdr) *elf_header = (ElfW(Ehdr) *) file_contents; + union + { + Elf64_Ehdr *eh64; + Elf32_Ehdr *eh32; + ElfW(Ehdr) *eh; + } + elf_header; int ret; - if (elf_header->e_ident [EI_CLASS] == ELFCLASS32) + elf_header.eh = file_contents; + if (elf_header.eh->e_ident [EI_CLASS] == ELFCLASS32) { - Elf32_Ehdr *elf32_header = (Elf32_Ehdr *) elf_header; - ret = process_elf32_file (file_name, lib, flag, osversion, soname, file_contents, file_length); + if (!ret) + { + Elf32_Word flags = elf_header.eh32->e_flags; + int nan2008 = (flags & EF_MIPS_NAN2008) != 0; - /* n32 libraries are always libc.so.6+. */ - if (!ret && (elf32_header->e_flags & EF_MIPS_ABI2) != 0) - *flag = FLAG_MIPS64_LIBN32|FLAG_ELF_LIBC6; + /* n32 libraries are always libc.so.6+, o32 only if 2008 NaN. */ + if ((flags & EF_MIPS_ABI2) != 0) + *flag = (nan2008 ? FLAG_MIPS64_LIBN32_NAN2008 + : FLAG_MIPS64_LIBN32) | FLAG_ELF_LIBC6; + else if (nan2008) + *flag = FLAG_MIPS_LIB32_NAN2008 | FLAG_ELF_LIBC6; + } } else { @@ -53,7 +66,13 @@ process_elf_file (const char *file_name, const char *lib, int *flag, file_contents, file_length); /* n64 libraries are always libc.so.6+. */ if (!ret) - *flag = FLAG_MIPS64_LIBN64|FLAG_ELF_LIBC6; + { + Elf64_Word flags = elf_header.eh64->e_flags; + int nan2008 = (flags & EF_MIPS_NAN2008) != 0; + + *flag = (nan2008 ? FLAG_MIPS64_LIBN64_NAN2008 + : FLAG_MIPS64_LIBN64) | FLAG_ELF_LIBC6; + } } return ret; |