diff --git a/Makeconfig b/Makeconfig index 1908f27..cf34ba1 100644 --- a/Makeconfig +++ b/Makeconfig @@ -775,7 +775,8 @@ endif # $(+cflags) == "" # current directory. +includes = -I$(..)include $(if $(subdir),$(objpfx:%/=-I%)) \ $(+sysdep-includes) $(includes) \ - $(patsubst %/,-I%,$(..)) $(libio-include) -I. $(sysincludes) + $(patsubst %/,-I%,$(..)) $(libio-include) -I. $(sysincludes) \ + -I$(common-objpfx)../shim/include # Since libio has several internal header files, we use a -I instead # of many little headers in the include directory. @@ -1033,7 +1034,7 @@ all-subdirs = csu assert ctype locale intl catgets math setjmp signal \ grp pwd posix io termios resource misc socket sysvipc gmon \ gnulib iconv iconvdata wctype manual shadow gshadow po argp \ crypt localedata timezone rt conform debug \ - $(add-on-subdirs) dlfcn elf + $(add-on-subdirs) dlfcn elf libos ifndef avoid-generated # sysd-sorted itself will contain rules making the sysd-sorted target diff --git a/Makefile b/Makefile index 51d4690..d72c4b0 100644 --- a/Makefile +++ b/Makefile @@ -177,6 +177,8 @@ $(inst_includedir)/gnu/stubs.h: $(+force) install-others-nosubdir: $(installed-stubs) endif +# For Graphene +CFLAGS-syscalldb.c = -fPIC # Since stubs.h is never needed when building the library, we simplify the # hairy installation process by producing it in place only as the last part diff --git a/Versions.def b/Versions.def index 759c754..e1a270e 100644 --- a/Versions.def +++ b/Versions.def @@ -41,6 +41,7 @@ libc { GCC_3.0 %endif GLIBC_PRIVATE + SHIM } libcrypt { GLIBC_2.0 @@ -50,6 +51,7 @@ libdl { GLIBC_2.1 GLIBC_2.3.3 GLIBC_2.3.4 + SHIM } libm { GLIBC_2.0 @@ -108,6 +110,7 @@ libpthread { GLIBC_2.18 GLIBC_2.19 GLIBC_PRIVATE + SHIM } libresolv { GLIBC_2.0 @@ -135,6 +138,7 @@ ld { GLIBC_2.3 GLIBC_2.4 GLIBC_PRIVATE + SHIM } libthread_db { GLIBC_2.1.3 @@ -148,3 +152,6 @@ libanl { libcidn { GLIBC_PRIVATE } +liblibos { + GLIBC_2.12 +} diff --git a/configure b/configure index fc023d0..b71c1f9 100755 --- a/configure +++ b/configure @@ -630,7 +630,8 @@ SED MAKEINFO MSGFMT MAKE -LD +LD_GOLD +LD_BFD AS OBJCOPY OBJDUMP @@ -4593,17 +4594,22 @@ if test $ac_verc_fail = yes; then AS=: critic_missing="$critic_missing as" fi -for ac_prog in $LD +LD_BFD= +LD_GOLD= +ld_is_gold="`$LD --version | sed -n 's/^GNU \(gold\).*$/\1/p'`" +if test -z "$ld_is_gold"; then + LD_BFD=$LD + for ac_prog in $LD_BFD do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_LD+:} false; then : +if ${ac_cv_prog_LD_BFD+:} false; then : $as_echo_n "(cached) " >&6 else - if test -n "$LD"; then - ac_cv_prog_LD="$LD" # Let the user override the test. + if test -n "$LD_BFD"; then + ac_cv_prog_LD_BFD="$LD_BFD" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH @@ -4612,7 +4618,7 @@ do test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_LD="$ac_prog" + ac_cv_prog_LD_BFD="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi @@ -4622,26 +4628,26 @@ IFS=$as_save_IFS fi fi -LD=$ac_cv_prog_LD -if test -n "$LD"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 -$as_echo "$LD" >&6; } +LD_BFD=$ac_cv_prog_LD_BFD +if test -n "$LD_BFD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD_BFD" >&5 +$as_echo "$LD_BFD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi - test -n "$LD" && break + test -n "$LD_BFD" && break done -if test -z "$LD"; then +if test -z "$LD_BFD"; then ac_verc_fail=yes else # Found it, now check the version. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking version of $LD" >&5 -$as_echo_n "checking version of $LD... " >&6; } - ac_prog_version=`$LD --version 2>&1 | sed -n 's/^.*GNU ld.* \([0-9][0-9]*\.[0-9.]*\).*$/\1/p'` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking version of $LD_BFD" >&5 +$as_echo_n "checking version of $LD_BFD... " >&6; } + ac_prog_version=`$LD_BFD --version 2>&1 | sed -n 's/^.*GNU ld.* \([0-9][0-9]*\.[0-9.]*\).*$/\1/p'` case $ac_prog_version in '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; 2.1[0-9][0-9]*|2.[2-9][0-9]*|[3-9].*|[1-9][0-9]*) @@ -4653,9 +4659,80 @@ $as_echo_n "checking version of $LD... " >&6; } $as_echo "$ac_prog_version" >&6; } fi if test $ac_verc_fail = yes; then - LD=: critic_missing="$critic_missing ld" + LD_BFD=: fi +else +# Accept gold 1.11 or higher. + LD_GOLD=$LD + for ac_prog in $LD_GOLD +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LD_GOLD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LD_GOLD"; then + ac_cv_prog_LD_GOLD="$LD_GOLD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_LD_GOLD="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LD_GOLD=$ac_cv_prog_LD_GOLD +if test -n "$LD_GOLD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD_GOLD" >&5 +$as_echo "$LD_GOLD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$LD_GOLD" && break +done + +if test -z "$LD_GOLD"; then + ac_verc_fail=yes +else + # Found it, now check the version. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking version of $LD_GOLD" >&5 +$as_echo_n "checking version of $LD_GOLD... " >&6; } + ac_prog_version=`$LD_GOLD --version 2>&1 | sed -n 's/^.*GNU gold.* \([0-9][0-9]*\.[0-9.]*\).*$/\1/p'` + case $ac_prog_version in + '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; + 1.1[1-9]*|1.[2-9][0-9]*|1.1[0-9][0-9]*|[2-9].*|[1-9][0-9]*) + ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;; + *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;; + + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_prog_version" >&5 +$as_echo "$ac_prog_version" >&6; } +fi +if test $ac_verc_fail = yes; then + LD_GOLD=: +fi + +fi +# Neither ld nor gold are new enough. +if test -z "$LD_BFD" && test -z "$LD_GOLD"; then + critic_missing="$critic_missing ld" +fi # These programs are version sensitive. @@ -6391,6 +6468,16 @@ $as_echo "$libc_cv_use_default_link" >&6; } use_default_link=$libc_cv_use_default_link fi +# The gold linker has no builtin default linker script, +# and the fallback of editing the builtin linker +# script is not available. Therefore if use_default_link +# is `no' then we can't use gold. This check is independent +# of gold's version and is used to sanity check that the +# linker continues to produce a useful shared link. +if test "$ld_is_gold" && test "$use_default_link" = "no"; then + as_fn_error $? "$LD did not generate a useful shared link. Try using GNU ld.bfd?" "$LINENO" 5 +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking linker output format" >&5 $as_echo_n "checking linker output format... " >&6; } if ${libc_cv_output_format+:} false; then : @@ -6409,6 +6496,17 @@ fi $as_echo "$libc_cv_output_format" >&6; } +# The gold linker has no builtin default linker script, +# and the fallback of parsing the builtin linker +# script to determine the target is not available. +# Therefore if libc_cv_output_format is `unknown' then +# we can't use gold. This check is independent of gold's +# version and is used to sanity check that the linker +# continues to support --print-output-format. +if test "$ld_is_gold" && test "$libc_cv_output_format" = "unknown"; then + as_fn_error $? "$LD did not support --print-output-format. Try using GNU ld.bfd?" "$LINENO" 5 +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fno-toplevel-reorder -fno-section-anchors" >&5 $as_echo_n "checking for -fno-toplevel-reorder -fno-section-anchors... " >&6; } if ${libc_cv_fno_toplevel_reorder+:} false; then : diff --git a/dlfcn/Versions b/dlfcn/Versions index 97902f0..c1874c1 100644 --- a/dlfcn/Versions +++ b/dlfcn/Versions @@ -14,4 +14,7 @@ libdl { GLIBC_PRIVATE { _dlfcn_hook; } + SHIM { + syscalldb; + } } diff --git a/elf/Makefile b/elf/Makefile index 4c58fc9..0ae2fa8 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -21,7 +21,7 @@ subdir := elf include ../Makeconfig -headers = elf.h bits/elfclass.h link.h bits/link.h +headers = elf.h bits/elfclass.h link.h bits/link.h syscalldb.h routines = $(dl-routines) dl-support dl-iteratephdr \ dl-addr enbl-secure dl-profstub \ dl-origin dl-libc dl-sym dl-tsd dl-sysdep @@ -31,7 +31,8 @@ routines = $(dl-routines) dl-support dl-iteratephdr \ dl-routines = $(addprefix dl-,load lookup object reloc deps hwcaps \ runtime error init fini debug misc \ version profile conflict tls origin scope \ - execstack caller open close trampoline) + execstack caller open close trampoline) \ + syscalldb syscallas ifeq (yes,$(use-ldconfig)) dl-routines += dl-cache endif diff --git a/elf/Versions b/elf/Versions index 2383992..98687f6 100644 --- a/elf/Versions +++ b/elf/Versions @@ -24,6 +24,9 @@ libc { _dl_sym; _dl_vsym; __libc_dlclose; __libc_dlopen_mode; __libc_dlsym; } + SHIM { + syscalldb; glibc_option; + } } ld { @@ -62,4 +65,7 @@ ld { # Pointer protection. __pointer_chk_guard; } + SHIM { + syscalldb; glibc_version; glibc_option; register_library; + } } diff --git a/elf/dl-debug.c b/elf/dl-debug.c index 4e7c593..3e0bff4 100644 --- a/elf/dl-debug.c +++ b/elf/dl-debug.c @@ -34,7 +34,7 @@ extern const int verify_link_map_members normally finds it via the DT_DEBUG entry in the dynamic section, but in a statically-linked program there is no dynamic section for the debugger to examine and it looks for this particular symbol name. */ -struct r_debug _r_debug; +struct r_debug __libc_r_debug; /* Initialize _r_debug if it has not already been done. The argument is @@ -48,7 +48,7 @@ _dl_debug_initialize (ElfW(Addr) ldbase, struct r_debug *r; if (ns == LM_ID_BASE) - r = &_r_debug; + r = &__libc_r_debug; else r = &GL(dl_ns)[ns]._ns_debug; @@ -56,9 +56,9 @@ _dl_debug_initialize (ElfW(Addr) ldbase, { /* Tell the debugger where to find the map of loaded objects. */ r->r_version = 1 /* R_DEBUG_VERSION XXX */; - r->r_ldbase = ldbase ?: _r_debug.r_ldbase; + r->r_ldbase = ldbase ?: __libc_r_debug.r_ldbase; r->r_map = (void *) GL(dl_ns)[ns]._ns_loaded; r->r_brk = (ElfW(Addr)) &_dl_debug_state; } return r; diff --git a/elf/dl-load.c b/elf/dl-load.c index 1be7a3c..c560ec1 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -39,6 +39,8 @@ #include +#include + /* On some systems, no flag bits are given to specify file mapping. */ #ifndef MAP_FILE # define MAP_FILE 0 @@ -1595,6 +1597,9 @@ cannot enable executable stack as shared object requires"); DL_AFTER_LOAD (l); #endif + /* register the library to SHIM */ + register_library(l->l_name, l->l_addr); + /* Now that the object is fully initialized add it to the object list. */ _dl_add_to_namespace_list (l, nsid); diff --git a/elf/link.h b/elf/link.h index d5905d1..f4e108a 100644 --- a/elf/link.h +++ b/elf/link.h @@ -65,6 +65,7 @@ struct r_debug /* This is the instance of that structure used by the dynamic linker. */ extern struct r_debug _r_debug; +asm (".symver _r_debug, __libc_r_debug@GLIBC_PRIVATE"); /* This symbol refers to the "dynamic structure" in the `.dynamic' section of whatever module refers to `_DYNAMIC'. So, to find its own diff --git a/elf/rtld.c b/elf/rtld.c index 6dcbabc..c87c773 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -356,6 +356,23 @@ _dl_start_final (void *arg, struct dl_start_final_info *info) return start_addr; } +/* For graphene, check if glibc version match to the compatible SHIM + library. If not, tell the user to update glibc. */ +#include "glibc-version.h" + +volatile const int glibc_version __attribute__((weak)) = GLIBC_VERSION; + +static void __attribute__((noinline,optimize("-O0"))) +check_glibc_version (void) +{ + if (glibc_version != GLIBC_VERSION) + { + _dl_fatal_printf ("Warning from Graphene: " + "Glibc version is incorrect. Please rebuild Glibc.\n"); + _exit (1); + } +} + static ElfW(Addr) __attribute_used__ internal_function _dl_start (void *arg) { @@ -546,6 +563,9 @@ _dl_start (void *arg) therefore need not test whether we have to allocate the array for the relocation results (as done in dl-reloc.c). */ + /* For Graphene, check if the glibc version is correct. */ + check_glibc_version(); + /* Now life is sane; we can call functions and access global data. Set up to use the operating system facilities, and find out from the operating system's program loader where to find the program @@ -1233,9 +1253,20 @@ of this helper program; chances are you did not intend to run this program.\n\ main_map->l_map_end = allocend; if ((ph->p_flags & PF_X) && allocend > main_map->l_text_end) main_map->l_text_end = allocend; + +#if 0 + ElfW(Addr) mapend = (allocend + GLRO(dl_pagesize) - 1) + & ~(GLRO(dl_pagesize) - 1); + int prot = ((ph->p_flags & PF_R) ? PROT_READ : 0)| + ((ph->p_flags & PF_W) ? PROT_WRITE : 0)| + ((ph->p_flags & PF_X) ? PROT_EXEC : 0); + __mmap ((void *) mapstart, mapend - mapstart, + prot, + MAP_ANON|MAP_PRIVATE|MAP_FIXED|0x20000000, + -1, 0); +#endif } break; - case PT_TLS: if (ph->p_memsz > 0) { @@ -1381,13 +1412,31 @@ of this helper program; chances are you did not intend to run this program.\n\ /* PT_GNU_RELRO is usually the last phdr. */ size_t cnt = rtld_ehdr->e_phnum; while (cnt-- > 0) + { if (rtld_phdr[cnt].p_type == PT_GNU_RELRO) { GL(dl_rtld_map).l_relro_addr = rtld_phdr[cnt].p_vaddr; GL(dl_rtld_map).l_relro_size = rtld_phdr[cnt].p_memsz; - break; } +#if 0 + if (rtld_phdr[cnt].p_type == PT_LOAD) + { + ElfW(Addr) mapstart = rtld_phdr[cnt].p_vaddr & ~(GLRO(dl_pagesize) - 1); + ElfW(Addr) mapend = (rtld_phdr[cnt].p_vaddr + rtld_phdr[cnt].p_memsz + + GLRO(dl_pagesize) - 1) + & ~(GLRO(dl_pagesize) - 1); + int prot = ((rtld_phdr[cnt].p_flags & PF_R) ? PROT_READ : 0)| + ((rtld_phdr[cnt].p_flags & PF_W) ? PROT_WRITE : 0)| + ((rtld_phdr[cnt].p_flags & PF_X) ? PROT_EXEC : 0); + __mmap ((void *) mapstart, mapend - mapstart, + prot, + MAP_ANON|MAP_PRIVATE|MAP_FIXED|0x20000000, + -1, 0); + } +#endif + } + /* Add the dynamic linker to the TLS list if it also uses TLS. */ if (GL(dl_rtld_map).l_tls_blocksize != 0) /* Assign a module ID. Do this before loading any audit modules. */ @@ -1636,89 +1654,6 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", } } - /* There usually is no ld.so.preload file, it should only be used - for emergencies and testing. So the open call etc should usually - fail. Using access() on a non-existing file is faster than using - open(). So we do this first. If it succeeds we do almost twice - the work but this does not matter, since it is not for production - use. */ - static const char preload_file[] = "/etc/ld.so.preload"; - if (__builtin_expect (__access (preload_file, R_OK) == 0, 0)) - { - /* Read the contents of the file. */ - file = _dl_sysdep_read_whole_file (preload_file, &file_size, - PROT_READ | PROT_WRITE); - if (__builtin_expect (file != MAP_FAILED, 0)) - { - /* Parse the file. It contains names of libraries to be loaded, - separated by white spaces or `:'. It may also contain - comments introduced by `#'. */ - char *problem; - char *runp; - size_t rest; - - /* Eliminate comments. */ - runp = file; - rest = file_size; - while (rest > 0) - { - char *comment = memchr (runp, '#', rest); - if (comment == NULL) - break; - - rest -= comment - runp; - do - *comment = ' '; - while (--rest > 0 && *++comment != '\n'); - } - - /* We have one problematic case: if we have a name at the end of - the file without a trailing terminating characters, we cannot - place the \0. Handle the case separately. */ - if (file[file_size - 1] != ' ' && file[file_size - 1] != '\t' - && file[file_size - 1] != '\n' && file[file_size - 1] != ':') - { - problem = &file[file_size]; - while (problem > file && problem[-1] != ' ' - && problem[-1] != '\t' - && problem[-1] != '\n' && problem[-1] != ':') - --problem; - - if (problem > file) - problem[-1] = '\0'; - } - else - { - problem = NULL; - file[file_size - 1] = '\0'; - } - - HP_TIMING_NOW (start); - - if (file != problem) - { - char *p; - runp = file; - while ((p = strsep (&runp, ": \t\n")) != NULL) - if (p[0] != '\0') - npreloads += do_preload (p, main_map, preload_file); - } - - if (problem != NULL) - { - char *p = strndupa (problem, file_size - (problem - file)); - - npreloads += do_preload (p, main_map, preload_file); - } - - HP_TIMING_NOW (stop); - HP_TIMING_DIFF (diff, start, stop); - HP_TIMING_ACCUM_NT (load_time, diff); - - /* We don't need the file anymore. */ - __munmap (file, file_size); - } - } if (__builtin_expect (*first_preload != NULL, 0)) { diff --git a/malloc/arena.c b/malloc/arena.c index 5088a25..33a3879 100644 --- a/malloc/arena.c +++ b/malloc/arena.c @@ -21,6 +21,27 @@ /* Compile-time constants. */ +#ifndef HEAP_MAX_SIZE +# ifdef DEFAULT_MMAP_THRESHOLD_MAX +# define DEFAULT_HEAP_MAX_SIZE (2 * DEFAULT_MMAP_THRESHOLD_MAX) +# else +# define DEFAULT_HEAP_MAX_SIZE (1024 * 1024) /* must be a power of two */ +# endif +# include +static long int heap_max_size = 0; +# define HEAP_MAX_SIZE \ + ({ \ + if (!heap_max_size) { \ + long int size = glibc_option("heap_size"); \ + if (size > 0) \ + heap_max_size = size; \ + else \ + heap_max_size = DEFAULT_HEAP_MAX_SIZE; \ + } \ + heap_max_size; \ + }) +#endif + #define HEAP_MIN_SIZE (32 * 1024) #ifndef HEAP_MAX_SIZE # ifdef DEFAULT_MMAP_THRESHOLD_MAX @@ -545,17 +566,6 @@ new_heap (size_t size, size_t top_pad) mapping (on Linux, this is the case for all non-writable mappings anyway). */ p2 = MAP_FAILED; - if (aligned_heap_area) - { - p2 = (char *) MMAP (aligned_heap_area, HEAP_MAX_SIZE, PROT_NONE, - MAP_NORESERVE); - aligned_heap_area = NULL; - if (p2 != MAP_FAILED && ((unsigned long) p2 & (HEAP_MAX_SIZE - 1))) - { - __munmap (p2, HEAP_MAX_SIZE); - p2 = MAP_FAILED; - } - } if (p2 == MAP_FAILED) { p1 = (char *) MMAP (0, HEAP_MAX_SIZE << 1, PROT_NONE, MAP_NORESERVE); @@ -566,8 +576,6 @@ new_heap (size_t size, size_t top_pad) ul = p2 - p1; if (ul) __munmap (p1, ul); - else - aligned_heap_area = p2 + HEAP_MAX_SIZE; __munmap (p2 + HEAP_MAX_SIZE, HEAP_MAX_SIZE - ul); } else diff --git a/nptl/Makefile b/nptl/Makefile index 57cc8c6..81f1bf4 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -20,7 +20,7 @@ # subdir := nptl -headers := pthread.h semaphore.h bits/semaphore.h +headers := pthread.h semaphore.h bits/semaphore.h syscalldb.h extra-libs := libpthread extra-libs-others := $(extra-libs) diff --git a/nptl/Versions b/nptl/Versions index bb11277..354149a 100644 --- a/nptl/Versions +++ b/nptl/Versions @@ -31,6 +31,9 @@ libc { # Internal libc interface to libpthread __libc_dl_error_tsd; } + SHIM { + syscalldb; glibc_option; + } } libpthread { @@ -262,4 +265,8 @@ libpthread { __pthread_clock_gettime; __pthread_clock_settime; __pthread_unwind; __pthread_get_minstack; } + + SHIM { + syscalldb; glibc_option; + } } diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c index 9d7f52f..72d50ae 100644 --- a/nptl/pthread_create.c +++ b/nptl/pthread_create.c @@ -405,8 +405,11 @@ start_thread (void *arg) # error "to do" #endif assert (freesize < pd->stackblock_size); + /* XXX: may not be necessary */ +#if 0 if (freesize > PTHREAD_STACK_MIN) __madvise (pd->stackblock, freesize - PTHREAD_STACK_MIN, MADV_DONTNEED); +#endif /* If the thread is detached free the TCB. */ if (IS_DETACHED (pd)) diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S b/nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S index 89fda5e..f6963f6 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/cancellation.S @@ -111,7 +111,8 @@ ENTRY(__pthread_disable_asynccancel) xorq %r10, %r10 addq $CANCELHANDLING, %rdi LOAD_PRIVATE_FUTEX_WAIT (%esi) - syscall + SYSCALLDB + movl %fs:CANCELHANDLING, %eax jmp 3b END(__pthread_disable_asynccancel) diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/fork.c b/nptl/sysdeps/unix/sysv/linux/x86_64/fork.c index a036b92..40a1eaf 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/fork.c +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/fork.c @@ -21,10 +21,20 @@ #include #include - -#define ARCH_FORK() \ +/* In Graphene, we prefer to call fork system call directly than clone */ +#if USE_clone_FOR_fork +# define ARCH_FORK() \ INLINE_SYSCALL (clone, 4, \ CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, 0, \ NULL, &THREAD_SELF->tid) +#else +# define ARCH_FORK() \ + ({ unsigned long ret = INLINE_SYSCALL (fork, 0); \ + if (!ret) { \ + pid_t pid = INLINE_SYSCALL (getpid, 0); \ + THREAD_SETMEM (THREAD_SELF, pid, pid); \ + THREAD_SETMEM (THREAD_SELF, tid, pid); \ + } ret; }) +#endif #include "../fork.c" diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S index f2dca07..0ce7c67 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S @@ -90,7 +90,7 @@ __lll_lock_wait_private: 1: LIBC_PROBE (lll_lock_wait_private, 1, %rdi) movl $SYS_futex, %eax - syscall + SYSCALLDB 2: movl %edx, %eax xchgl %eax, (%rdi) /* NB: lock is implied */ @@ -130,7 +130,7 @@ __lll_lock_wait: 1: LIBC_PROBE (lll_lock_wait, 2, %rdi, %rsi) movl $SYS_futex, %eax - syscall + SYSCALLDB 2: movl %edx, %eax xchgl %eax, (%rdi) /* NB: lock is implied */ @@ -185,7 +185,7 @@ __lll_timedlock_wait: 1: movl $SYS_futex, %eax movl $2, %edx - syscall + SYSCALLDB 2: xchgl %edx, (%rdi) /* NB: lock is implied */ @@ -279,7 +279,7 @@ __lll_timedlock_wait: LOAD_FUTEX_WAIT (%esi) movq %r12, %rdi movl $SYS_futex, %eax - syscall + SYSCALLDB /* NB: %edx == 2 */ xchgl %edx, (%r12) @@ -336,7 +336,7 @@ __lll_unlock_wake_private: LOAD_PRIVATE_FUTEX_WAKE (%esi) movl $1, %edx /* Wake one thread. */ movl $SYS_futex, %eax - syscall + SYSCALLDB popq %rdx cfi_adjust_cfa_offset(-8) @@ -366,7 +366,7 @@ __lll_unlock_wake: LOAD_FUTEX_WAKE (%esi) movl $1, %edx /* Wake one thread. */ movl $SYS_futex, %eax - syscall + SYSCALLDB popq %rdx cfi_adjust_cfa_offset(-8) @@ -435,7 +435,7 @@ __lll_timedwait_tid: #endif movq %r12, %rdi movl $SYS_futex, %eax - syscall + SYSCALLDB cmpl $0, (%rdi) jne 1f diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h index 0a26739..8aae14a 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h @@ -214,7 +214,7 @@ LLL_STUB_UNWIND_INFO_END register const struct timespec *__to __asm ("r10") = timeout; \ int __status; \ register __typeof (val) _val __asm ("edx") = (val); \ - __asm __volatile ("syscall" \ + __asm __volatile (SYSCALLDB \ : "=a" (__status) \ : "0" (SYS_futex), "D" (futex), \ "S" (__lll_private_flag (FUTEX_WAIT, private)), \ @@ -229,7 +229,7 @@ LLL_STUB_UNWIND_INFO_END int __status; \ register __typeof (nr) _nr __asm ("edx") = (nr); \ LIBC_PROBE (lll_futex_wake, 3, futex, nr, private); \ - __asm __volatile ("syscall" \ + __asm __volatile (SYSCALLDB \ : "=a" (__status) \ : "0" (SYS_futex), "D" (futex), \ "S" (__lll_private_flag (FUTEX_WAKE, private)), \ @@ -540,7 +540,7 @@ extern int __lll_timedlock_elision (int *futex, short *adapt_count, { \ int ignore; \ __asm __volatile (LOCK_INSTR "orl %3, (%2)\n\t" \ - "syscall" \ + SYSCALLDB \ : "=m" (futex), "=a" (ignore) \ : "D" (&(futex)), "i" (FUTEX_OWNER_DIED), \ "S" (__lll_private_flag (FUTEX_WAKE, private)), \ @@ -555,7 +555,7 @@ extern int __lll_timedlock_elision (int *futex, short *adapt_count, register int __nr_move __asm ("r10") = nr_move; \ register void *__mutex __asm ("r8") = mutex; \ register int __val __asm ("r9") = val; \ - __asm __volatile ("syscall" \ + __asm __volatile (SYSCALLDB \ : "=a" (__res) \ : "0" (__NR_futex), "D" ((void *) ftx), \ "S" (__lll_private_flag (FUTEX_CMP_REQUEUE, \ @@ -581,7 +581,7 @@ extern int __lll_timedlock_elision (int *futex, short *adapt_count, if (_tid != 0) \ __asm __volatile ("xorq %%r10, %%r10\n\t" \ "1:\tmovq %2, %%rax\n\t" \ - "syscall\n\t" \ + SYSCALLDB \ "cmpl $0, (%%rdi)\n\t" \ "jne 1b" \ : "=&a" (__ignore) \ diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S index 990b6f9..b01214d 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S @@ -80,7 +80,7 @@ __lll_robust_lock_wait: jnz 2f 1: movl $SYS_futex, %eax - syscall + SYSCALLDB movl (%rdi), %eax @@ -145,7 +145,7 @@ __lll_robust_timedlock_wait: jnz 6f 5: movl $SYS_futex, %eax - syscall + SYSCALLDB movl %eax, %ecx movl (%rdi), %eax @@ -257,7 +257,7 @@ __lll_robust_timedlock_wait: LOAD_FUTEX_WAIT (%esi) movq %r12, %rdi movl $SYS_futex, %eax - syscall + SYSCALLDB movq %rax, %rcx movl (%r12), %eax diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S index eec17f2..a350340 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_barrier_wait.S @@ -62,7 +62,7 @@ pthread_barrier_wait: #endif xorq %r10, %r10 8: movl $SYS_futex, %eax - syscall + SYSCALLDB /* Don't return on spurious wakeups. The syscall does not change any register except %eax so there is no need to reload any of @@ -109,7 +109,7 @@ pthread_barrier_wait: movl $FUTEX_WAKE, %esi orl PRIVATE(%rdi), %esi movl $SYS_futex, %eax - syscall + SYSCALLDB /* Increment LEFT. If this brings the count back to the initial count unlock the object. */ diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S index 985e0f1..d559456 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S @@ -90,7 +90,7 @@ __pthread_cond_broadcast: movl $SYS_futex, %eax movl $1, %edx movl $0x7fffffff, %r10d - syscall + SYSCALLDB /* For any kind of error, which mainly is EAGAIN, we try again with WAKE. The general test also covers running on old @@ -106,7 +106,7 @@ __pthread_cond_broadcast: movl $SYS_futex, %eax movl $1, %edx movl $0x7fffffff, %r10d - syscall + SYSCALLDB /* For any kind of error, which mainly is EAGAIN, we try again with WAKE. The general test also covers running on old @@ -172,7 +172,7 @@ __pthread_cond_broadcast: orl $FUTEX_WAKE, %esi #endif movl $SYS_futex, %eax - syscall + SYSCALLDB jmp 10b .size __pthread_cond_broadcast, .-__pthread_cond_broadcast versioned_symbol (libpthread, __pthread_cond_broadcast, pthread_cond_broadcast, diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S index 53d65b6..16df581 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S @@ -82,7 +82,7 @@ __pthread_cond_signal: addq $cond_lock, %r8 #endif movl $FUTEX_OP_CLEAR_WAKE_IF_GT_ONE, %r9d - syscall + SYSCALLDB #if cond_lock != 0 subq $cond_lock, %r8 #endif @@ -99,7 +99,7 @@ __pthread_cond_signal: movq %rcx, %r8 xorq %r10, %r10 movl (%rdi), %r9d // XXX Can this be right? - syscall + SYSCALLDB leaq -cond_futex(%rdi), %r8 @@ -118,7 +118,7 @@ __pthread_cond_signal: movl $SYS_futex, %eax /* %rdx should be 1 already from $FUTEX_WAKE_OP syscall. movl $1, %edx */ - syscall + SYSCALLDB /* Unlock. */ 4: LOCK diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S index 0dc2340..8aff242 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S @@ -188,7 +188,7 @@ __pthread_cond_timedwait: movq %r12, %rdx addq $cond_futex, %rdi movl $SYS_futex, %eax - syscall + SYSCALLDB cmpl $0, %eax sete %r15b @@ -234,7 +234,7 @@ __pthread_cond_timedwait: movq %r12, %rdx addq $cond_futex, %rdi movl $SYS_futex, %eax - syscall + SYSCALLDB 62: movq %rax, %r14 movl (%rsp), %edi @@ -321,7 +321,7 @@ __pthread_cond_timedwait: orl $FUTEX_WAKE, %esi #endif movl $SYS_futex, %eax - syscall + SYSCALLDB subq $cond_nwaiters, %rdi 55: LOCK @@ -485,15 +485,8 @@ __pthread_cond_timedwait: /* Only clocks 0 and 1 are allowed so far. Both are handled in the kernel. */ leaq 32(%rsp), %rsi -# ifdef SHARED - mov __vdso_clock_gettime@GOTPCREL(%rip), %RAX_LP - mov (%rax), %RAX_LP - PTR_DEMANGLE (%RAX_LP) - call *%rax -# else movl $__NR_clock_gettime, %eax - syscall -# endif + SYSCALLDB /* Compute relative timeout. */ movq (%r13), %rcx @@ -560,7 +553,7 @@ __pthread_cond_timedwait: # endif addq $cond_futex, %rdi movl $SYS_futex, %eax - syscall + SYSCALLDB movq %rax, %r14 movl (%rsp), %edi @@ -732,7 +725,7 @@ __condvar_cleanup2: orl $FUTEX_WAKE, %esi #endif movl $SYS_futex, %eax - syscall + SYSCALLDB subq $cond_nwaiters, %rdi movl $1, %r12d @@ -769,7 +762,7 @@ __condvar_cleanup2: orl $FUTEX_WAKE, %esi #endif movl $SYS_futex, %eax - syscall + SYSCALLDB /* Lock the mutex only if we don't own it already. This only happens in case of PI mutexes, if we got cancelled after a successful diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S index 0e61d0a..b4bcc15 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S @@ -138,7 +138,7 @@ __pthread_cond_wait: movl $(FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG), %esi movl $SYS_futex, %eax - syscall + SYSCALLDB cmpl $0, %eax sete %r8b @@ -180,7 +180,7 @@ __pthread_cond_wait: #endif 60: xorb %r8b, %r8b movl $SYS_futex, %eax - syscall + SYSCALLDB 62: movl (%rsp), %edi callq __pthread_disable_asynccancel @@ -239,7 +239,7 @@ __pthread_cond_wait: orl $FUTEX_WAKE, %esi #endif movl $SYS_futex, %eax - syscall + SYSCALLDB subq $cond_nwaiters, %rdi 17: LOCK @@ -455,7 +455,7 @@ __condvar_cleanup1: orl $FUTEX_WAKE, %esi #endif movl $SYS_futex, %eax - syscall + SYSCALLDB subq $cond_nwaiters, %rdi movl $1, %ecx @@ -493,7 +493,7 @@ __condvar_cleanup1: orl $FUTEX_WAKE, %esi #endif movl $SYS_futex, %eax - syscall + SYSCALLDB /* Lock the mutex only if we don't own it already. This only happens in case of PI mutexes, if we got cancelled after a successful diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S index 2cbe2fa..489998a 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_once.S @@ -90,7 +90,7 @@ __pthread_once: # endif #endif movl $SYS_futex, %eax - syscall + SYSCALLDB jmp 6b /* Preserve the pointer to the control variable. */ @@ -123,7 +123,7 @@ __pthread_once: orl %fs:PRIVATE_FUTEX, %esi #endif movl $SYS_futex, %eax - syscall + SYSCALLDB 4: addq $8, %rsp cfi_adjust_cfa_offset(-8) @@ -152,7 +152,7 @@ clear_once_control: orl %fs:PRIVATE_FUTEX, %esi #endif movl $SYS_futex, %eax - syscall + SYSCALLDB movq %r8, %rdi .LcallUR: diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S index 3bbb4c7..53d5ca6 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_rdlock.S @@ -82,7 +82,7 @@ __pthread_rwlock_rdlock: #endif addq $READERS_WAKEUP, %rdi movl $SYS_futex, %eax - syscall + SYSCALLDB subq $READERS_WAKEUP, %rdi diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S index 40bcc04..348170e 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S @@ -109,7 +109,7 @@ pthread_rwlock_timedrdlock: #endif 21: leaq READERS_WAKEUP(%r12), %rdi movl $SYS_futex, %eax - syscall + SYSCALLDB movq %rax, %rdx #ifndef __ASSUME_FUTEX_CLOCK_REALTIME diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S index f57ef52..e9ac77f 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S @@ -106,7 +106,7 @@ pthread_rwlock_timedwrlock: #endif 21: leaq WRITERS_WAKEUP(%r12), %rdi movl $SYS_futex, %eax - syscall + SYSCALLDB movq %rax, %rdx #ifndef __ASSUME_FUTEX_CLOCK_REALTIME diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S index d779f7b..849c74f 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_unlock.S @@ -79,7 +79,7 @@ __pthread_rwlock_unlock: #endif movl $SYS_futex, %eax movq %r10, %rdi - syscall + SYSCALLDB xorl %eax, %eax retq diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S index e444def..fd94930 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_wrlock.S @@ -80,7 +80,7 @@ __pthread_rwlock_wrlock: #endif addq $WRITERS_WAKEUP, %rdi movl $SYS_futex, %eax - syscall + SYSCALLDB subq $WRITERS_WAKEUP, %rdi diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S index 1c11600..bd166cf 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S @@ -52,7 +52,7 @@ sem_post: movl $FUTEX_WAKE, %esi orl PRIVATE(%rdi), %esi movl $1, %edx - syscall + SYSCALLDB testq %rax, %rax js 1f diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S index 880610e..e520049 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S @@ -97,7 +97,7 @@ sem_timedwait: orl PRIVATE(%rdi), %esi movl $SYS_futex, %eax xorl %edx, %edx - syscall + SYSCALLDB movq %rax, %r9 #if VALUE != 0 leaq -VALUE(%rdi), %rdi @@ -233,7 +233,7 @@ sem_timedwait: # endif movl $SYS_futex, %eax xorl %edx, %edx - syscall + SYSCALLDB movq %rax, %r14 movl 16(%rsp), %edi diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S index 8f4d068..fe6dfbf 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S @@ -81,7 +81,7 @@ sem_wait: orl PRIVATE(%rdi), %esi #endif xorl %edx, %edx - syscall + SYSCALLDB movq %rax, %rcx xchgq %r8, %rdi diff --git a/nptl/sysdeps/x86_64/pthreaddef.h b/nptl/sysdeps/x86_64/pthreaddef.h index 18a15a1..f050241 100644 --- a/nptl/sysdeps/x86_64/pthreaddef.h +++ b/nptl/sysdeps/x86_64/pthreaddef.h @@ -48,4 +48,4 @@ /* While there is no such syscall. */ #define __exit_thread_inline(val) \ - asm volatile ("syscall" :: "a" (__NR_exit), "D" (val)) + asm volatile (SYSCALLDB :: "a" (__NR_exit), "D" (val)) diff --git a/nptl/sysdeps/x86_64/tls.h b/nptl/sysdeps/x86_64/tls.h index cbb5e9e..9b87e25 100644 --- a/nptl/sysdeps/x86_64/tls.h +++ b/nptl/sysdeps/x86_64/tls.h @@ -28,6 +28,8 @@ # include # include # include +# include +# include /* Replacement type for __m128 since this file is included by ld.so, which is compiled with -mno-sse. It must not change the alignment @@ -67,6 +69,10 @@ typedef struct # else int __glibc_reserved1; # endif + + shim_tcb_t shim_tcb; /* For graphene, we allocate a shim_tcb + in the real tcb. */ + int rtld_must_xmm_save; /* Reservation of some values for the TM ABI. */ void *__private_tm[4]; @@ -137,7 +143,6 @@ typedef struct # define GET_DTV(descr) \ (((tcbhead_t *) (descr))->dtv) - /* Code to initially initialize the thread pointer. This might need special attention since 'errno' is not yet available and if the operation can cause a failure 'errno' must not be touched. @@ -154,7 +159,7 @@ typedef struct _head->self = _thrdescr; \ \ /* It is a simple syscall to set the %fs value for the thread. */ \ - asm volatile ("syscall" \ + asm volatile (SYSCALLDB \ : "=a" (_result) \ : "0" ((unsigned long int) __NR_arch_prctl), \ "D" ((unsigned long int) ARCH_SET_FS), \ diff --git a/scripts/mkinstalldirs b/scripts/mkinstalldirs index 55d537f..57bf12b 100755 --- a/scripts/mkinstalldirs +++ b/scripts/mkinstalldirs @@ -126,9 +126,9 @@ do esac if test ! -d "$pathcomp"; then - echo "mkdir $pathcomp" + echo "mkdir -p $pathcomp" - mkdir "$pathcomp" || lasterr=$? + mkdir -p "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr diff --git a/shlib-versions b/shlib-versions index 78b0ad7..5c3dcf2 100644 --- a/shlib-versions +++ b/shlib-versions @@ -108,3 +108,5 @@ sparc64.*-.*-.* libBrokenLocale=1 GLIBC_2.2 # This defines the libgcc soname version this glibc is to load for # asynchronous cancellation to work correctly. .*-.*-.* libgcc_s=1 + +.*-.*-.* liblibos=1 diff --git a/sysdeps/unix/sysv/linux/_exit.c b/sysdeps/unix/sysv/linux/_exit.c index 2468228..a9f1cd6 100644 --- a/sysdeps/unix/sysv/linux/_exit.c +++ b/sysdeps/unix/sysv/linux/_exit.c @@ -29,9 +29,9 @@ _exit (status) while (1) { #ifdef __NR_exit_group - INLINE_SYSCALL (exit_group, 1, status); + INLINE_SYSCALL_ASM (exit_group, 1, status); #endif - INLINE_SYSCALL (exit, 1, status); + INLINE_SYSCALL_ASM (exit, 1, status); #ifdef ABORT_INSTRUCTION ABORT_INSTRUCTION; diff --git a/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S b/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S index 49f0384..6b1a975 100644 --- a/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S +++ b/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S @@ -84,7 +84,8 @@ ENTRY(____longjmp_chk) xorl %edi, %edi lea -sizeSS(%rsp), %RSI_LP movl $__NR_sigaltstack, %eax - syscall + SYSCALLDB + /* Without working sigaltstack we cannot perform the test. */ testl %eax, %eax jne .Lok2 diff --git a/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c b/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c index f712110..f6bad14 100644 --- a/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c +++ b/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c @@ -1,5 +1,6 @@ #include "bits/libc-vdso.h" +#if 0 /* in Graphene, disallow VDSO calls */ #ifdef SHARED # define SYSCALL_GETTIME(id, tp) \ ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \ @@ -16,5 +17,6 @@ PTR_DEMANGLE (f); \ f (id, tp); }) #endif +#endif #include "../clock_gettime.c" diff --git a/sysdeps/unix/sysv/linux/x86_64/clone.S b/sysdeps/unix/sysv/linux/x86_64/clone.S index 0508730..e1b35ec 100644 --- a/sysdeps/unix/sysv/linux/x86_64/clone.S +++ b/sysdeps/unix/sysv/linux/x86_64/clone.S @@ -59,11 +59,15 @@ ENTRY (__clone) jz SYSCALL_ERROR_LABEL /* Insert the argument onto the new stack. */ - subq $16,%rsi - movq %rcx,8(%rsi) + subq $24,%rsi + movq %rcx,16(%rsi) /* Save the function pointer. It will be popped off in the child in the ebx frobbing below. */ + movq %rdi,8(%rsi) + + /* Push an additional pointer as return address into the stack */ + leaq L(clone_return)(%rip),%rdi movq %rdi,0(%rsi) /* Do the system call. */ @@ -76,8 +80,9 @@ ENTRY (__clone) /* End FDE now, because in the child the unwind info will be wrong. */ cfi_endproc; - syscall + SYSCALLDB +L(clone_return): testq %rax,%rax jl SYSCALL_ERROR_LABEL jz L(thread_start) @@ -99,13 +104,14 @@ L(thread_start): movl $-1, %eax jne 2f movl $SYS_ify(getpid), %eax - syscall + SYSCALLDB 2: movl %eax, %fs:PID movl %eax, %fs:TID 1: #endif /* Set up arguments for the function call. */ + addq $8,%rsp /* Skip the return address */ popq %rax /* Function to call. */ popq %rdi /* Argument. */ call *%rax diff --git a/sysdeps/unix/sysv/linux/x86_64/getcontext.S b/sysdeps/unix/sysv/linux/x86_64/getcontext.S index 140db03..6967f10 100644 --- a/sysdeps/unix/sysv/linux/x86_64/getcontext.S +++ b/sysdeps/unix/sysv/linux/x86_64/getcontext.S @@ -75,7 +75,7 @@ ENTRY(__getcontext) #endif movl $_NSIG8,%r10d movl $__NR_rt_sigprocmask, %eax - syscall + SYSCALLDB cmpq $-4095, %rax /* Check %rax for error. */ jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */ diff --git a/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c b/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c index 440ca7f..571125d 100644 --- a/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c +++ b/sysdeps/unix/sysv/linux/x86_64/gettimeofday.c @@ -17,6 +17,7 @@ #include +#if 0 /* In graphene, do not use vsyscall or VDSO call */ #ifdef SHARED # include @@ -42,7 +43,8 @@ asm (".type __gettimeofday, %gnu_indirect_function"); asm (".globl __GI___gettimeofday\n" "__GI___gettimeofday = __gettimeofday"); -#else +#endif +#endif # include # include @@ -54,6 +56,5 @@ __gettimeofday (struct timeval *tv, struct timezone *tz) } libc_hidden_def (__gettimeofday) -#endif weak_alias (__gettimeofday, gettimeofday) libc_hidden_weak (gettimeofday) diff --git a/sysdeps/unix/sysv/linux/x86_64/sched_getcpu.S b/sysdeps/unix/sysv/linux/x86_64/sched_getcpu.S index 0fd47f2..7a82975 100644 --- a/sysdeps/unix/sysv/linux/x86_64/sched_getcpu.S +++ b/sysdeps/unix/sysv/linux/x86_64/sched_getcpu.S @@ -30,6 +30,7 @@ ENTRY (sched_getcpu) sub $0x8, %rsp cfi_adjust_cfa_offset(8) +#if 0 /* for Graphene, never do VDSO calls */ movq %rsp, %rdi xorl %esi, %esi movl $VGETCPU_CACHE_OFFSET, %edx @@ -39,16 +40,19 @@ ENTRY (sched_getcpu) movq __vdso_getcpu(%rip), %rax PTR_DEMANGLE (%rax) callq *%rax -#else -# ifdef __NR_getcpu +#endif +#endif + +#ifdef __NR_getcpu movl $__NR_getcpu, %eax - syscall -# ifndef __ASSUME_GETCPU_SYSCALL + SYSCALLDB +#endif + +#if 0 /* for Graphene, never do vsyscall */ +# ifndef __ASSUME_GETCPU_SYSCALL cmpq $-ENOSYS, %rax jne 1f -# endif -# endif -# ifndef __ASSUME_GETCPU_SYSCALL + movq $VSYSCALL_ADDR_vgetcpu, %rax callq *%rax 1: diff --git a/sysdeps/unix/sysv/linux/x86_64/setcontext.S b/sysdeps/unix/sysv/linux/x86_64/setcontext.S index b726fa0..bb3ae34 100644 --- a/sysdeps/unix/sysv/linux/x86_64/setcontext.S +++ b/sysdeps/unix/sysv/linux/x86_64/setcontext.S @@ -43,7 +43,7 @@ ENTRY(__setcontext) movl $SIG_SETMASK, %edi movl $_NSIG8,%r10d movl $__NR_rt_sigprocmask, %eax - syscall + SYSCALLDB popq %rdi /* Reload %rdi, adjust stack. */ cfi_adjust_cfa_offset(-8) cmpq $-4095, %rax /* Check %rax for error. */ diff --git a/sysdeps/unix/sysv/linux/x86_64/sigaction.c b/sysdeps/unix/sysv/linux/x86_64/sigaction.c index ab23985..38a6b69 100644 --- a/sysdeps/unix/sysv/linux/x86_64/sigaction.c +++ b/sysdeps/unix/sysv/linux/x86_64/sigaction.c @@ -129,7 +129,7 @@ asm \ " .type __" #name ",@function\n" \ "__" #name ":\n" \ " movq $" #syscall ", %rax\n" \ - " syscall\n" \ + SYSCALLDB_ASM \ ".LEND_" #name ":\n" \ ".section .eh_frame,\"a\",@progbits\n" \ ".LSTARTFRAME_" #name ":\n" \ diff --git a/sysdeps/unix/sysv/linux/x86_64/swapcontext.S b/sysdeps/unix/sysv/linux/x86_64/swapcontext.S index b3854fa..6369bfe 100644 --- a/sysdeps/unix/sysv/linux/x86_64/swapcontext.S +++ b/sysdeps/unix/sysv/linux/x86_64/swapcontext.S @@ -75,7 +75,7 @@ ENTRY(__swapcontext) movl $SIG_SETMASK, %edi movl $_NSIG8,%r10d movl $__NR_rt_sigprocmask, %eax - syscall + SYSCALLDB cmpq $-4095, %rax /* Check %rax for error. */ jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */ diff --git a/sysdeps/unix/sysv/linux/x86_64/syscall.S b/sysdeps/unix/sysv/linux/x86_64/syscall.S index 92c2f5b..e32ebb2 100644 --- a/sysdeps/unix/sysv/linux/x86_64/syscall.S +++ b/sysdeps/unix/sysv/linux/x86_64/syscall.S @@ -31,10 +31,12 @@ movq %rsi, %rdi /* shift arg1 - arg5. */ movq %rdx, %rsi movq %rcx, %rdx + /* DEP 8/17/17: Keep kernel calling + * convention and fix in libOS */ movq %r8, %r10 movq %r9, %r8 movq 8(%rsp),%r9 /* arg6 is on the stack. */ - syscall /* Do the system call. */ + SYSCALLDB /* Do the system call. */ cmpq $-4095, %rax /* Check %rax for error. */ jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */ ret /* Return to caller. */ diff --git a/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/sysdep.h index 4a9a9d9..dc452ed 100644 --- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h +++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h @@ -21,6 +21,7 @@ /* There is some commonality. */ #include #include +#include "syscalldb.h" #ifdef IS_IN_rtld # include /* Defines RTLD_PRIVATE_ERRNO. */ @@ -176,7 +177,7 @@ # define DO_CALL(syscall_name, args) \ DOARGS_##args \ movl $SYS_ify (syscall_name), %eax; \ - syscall; + SYSCALLDB # define DOARGS_0 /* nothing */ # define DOARGS_1 /* nothing */ @@ -190,9 +191,20 @@ /* Define a macro which expands inline into the wrapper code for a system call. */ # undef INLINE_SYSCALL -# define INLINE_SYSCALL(name, nr, args...) \ +# define INLINE_SYSCALL(name, nr_args...) \ ({ \ - unsigned long int resultvar = INTERNAL_SYSCALL (name, , nr, args); \ + unsigned long int resultvar = INTERNAL_SYSCALL (name, , ##nr_args); \ + if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (resultvar, ), 0)) \ + { \ + __set_errno (INTERNAL_SYSCALL_ERRNO (resultvar, )); \ + resultvar = (unsigned long int) -1; \ + } \ + (long int) resultvar; }) + +# undef INLINE_SYSCALL_ASM +# define INLINE_SYSCALL_ASM(name, nr_args...) \ + ({ \ + unsigned long int resultvar = INTERNAL_SYSCALL_ASM (name, , ##nr_args); \ if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (resultvar, ), 0)) \ { \ __set_errno (INTERNAL_SYSCALL_ERRNO (resultvar, )); \ @@ -204,9 +216,9 @@ into the wrapper code for a system call. It should be used when size of any argument > size of long int. */ # undef INLINE_SYSCALL_TYPES -# define INLINE_SYSCALL_TYPES(name, nr, args...) \ +# define INLINE_SYSCALL_TYPES(name, nr_args...) \ ({ \ - unsigned long int resultvar = INTERNAL_SYSCALL_TYPES (name, , nr, args); \ + unsigned long int resultvar = INTERNAL_SYSCALL_TYPES (name, , ##nr_args); \ if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (resultvar, ), 0)) \ { \ __set_errno (INTERNAL_SYSCALL_ERRNO (resultvar, )); \ @@ -223,13 +235,19 @@ LOAD_ARGS_##nr (args) \ LOAD_REGS_##nr \ asm volatile ( \ - "syscall\n\t" \ + SYSCALLDB \ : "=a" (resultvar) \ : "0" (name) ASM_ARGS_##nr : "memory", "cc", "r11", "cx"); \ (long int) resultvar; }) +# define INTERNAL_SYSCALL_NCS_ASM INTERNAL_SYSCALL_NCS + # undef INTERNAL_SYSCALL -# define INTERNAL_SYSCALL(name, err, nr, args...) \ - INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args) +# define INTERNAL_SYSCALL(name, err, nr_args...) \ + INTERNAL_SYSCALL_NCS (__NR_##name, err, ##nr_args) + +# undef INTERNAL_SYSCALL_ASM +# define INTERNAL_SYSCALL_ASM(name, err, nr_args...) \ + INTERNAL_SYSCALL_NCS_ASM (__NR_##name, err, ##nr_args) # define INTERNAL_SYSCALL_NCS_TYPES(name, err, nr, args...) \ ({ \ @@ -237,7 +255,7 @@ LOAD_ARGS_TYPES_##nr (args) \ LOAD_REGS_TYPES_##nr (args) \ asm volatile ( \ - "syscall\n\t" \ + SYSCALLDB \ : "=a" (resultvar) \ : "0" (name) ASM_ARGS_##nr : "memory", "cc", "r11", "cx"); \ (long int) resultvar; }) @@ -252,6 +270,7 @@ # undef INTERNAL_SYSCALL_ERRNO # define INTERNAL_SYSCALL_ERRNO(val, err) (-(val)) +# if 0 /* for Graphene, never do vsyscall */ # ifdef SHARED # define INLINE_VSYSCALL(name, nr, args...) \ ({ \ @@ -300,12 +319,13 @@ v_ret; \ }) -# else -# define INLINE_VSYSCALL(name, nr, args...) \ - INLINE_SYSCALL (name, nr, ##args) -# define INTERNAL_VSYSCALL(name, err, nr, args...) \ - INTERNAL_SYSCALL (name, err, nr, ##args) # endif +# endif + +# define INLINE_VSYSCALL(name, nr_args...) \ + INLINE_SYSCALL (name, ##nr_args) +# define INTERNAL_VSYSCALL(name, err, nr_args...) \ + INTERNAL_SYSCALL (name, err, ##nr_args) # define LOAD_ARGS_0() # define LOAD_REGS_0 diff --git a/sysdeps/unix/sysv/linux/x86_64/time.c b/sysdeps/unix/sysv/linux/x86_64/time.c deleted file mode 100644 index 79f1fab..0000000 --- a/sysdeps/unix/sysv/linux/x86_64/time.c +++ /dev/null @@ -1,60 +0,0 @@ -/* Copyright (C) 2001-2014 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#ifdef SHARED -/* Redefine time so that the compiler won't complain about the type - mismatch with the IFUNC selector in strong_alias, below. */ -#undef time -#define time __redirect_time -#include - -#include - -#define VSYSCALL_ADDR_vtime 0xffffffffff600400 - -/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle - ifunc symbol properly. */ -extern __typeof (__redirect_time) __libc_time; -void *time_ifunc (void) __asm__ ("__libc_time"); - -void * -time_ifunc (void) -{ - PREPARE_VERSION (linux26, "LINUX_2.6", 61765110); - - /* If the vDSO is not available we fall back on the old vsyscall. */ - return _dl_vdso_vsym ("__vdso_time", &linux26) ?: (void *) VSYSCALL_ADDR_vtime; -} -__asm (".type __libc_time, %gnu_indirect_function"); - -#undef time -strong_alias (__libc_time, time) -libc_hidden_ver (__libc_time, time) - -#else - -# include -# include - -time_t -time (time_t *t) -{ - INTERNAL_SYSCALL_DECL (err); - return INTERNAL_SYSCALL (time, err, 1, t); -} - -#endif diff --git a/sysdeps/unix/sysv/linux/x86_64/vfork.S b/sysdeps/unix/sysv/linux/x86_64/vfork.S index d3b450a..75a63e1 100644 --- a/sysdeps/unix/sysv/linux/x86_64/vfork.S +++ b/sysdeps/unix/sysv/linux/x86_64/vfork.S @@ -38,7 +38,7 @@ ENTRY (__vfork) /* Stuff the syscall number in RAX and enter into the kernel. */ movl $SYS_ify (vfork), %eax - syscall + SYSCALLDB /* Push back the return PC. */ pushq %rdi diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h index 504c95f..dcfc259 100644 --- a/sysdeps/x86_64/dl-machine.h +++ b/sysdeps/x86_64/dl-machine.h @@ -529,7 +529,8 @@ elf_machine_lazy_rel (struct link_map *map, value = ((ElfW(Addr) (*) (void)) value) (); *reloc_addr = value; } - else + /* for graphene, get around R_X86_64_NONE */ + else if (__builtin_expect (r_type != R_X86_64_NONE, 1)) _dl_reloc_bad_type (map, r_type, 1); } diff --git a/sysdeps/x86_64/hp-timing.h b/sysdeps/x86_64/hp-timing.h index d88206c..886c500 100644 --- a/sysdeps/x86_64/hp-timing.h +++ b/sysdeps/x86_64/hp-timing.h @@ -18,23 +18,6 @@ #ifndef _HP_TIMING_H -/* We can use some of the i686 implementation without changes. */ -# include - -/* The "=A" constraint used in 32-bit mode does not work in 64-bit mode. */ -# undef HP_TIMING_NOW -# define HP_TIMING_NOW(Var) \ - ({ unsigned int _hi, _lo; \ - asm volatile ("rdtsc" : "=a" (_lo), "=d" (_hi)); \ - (Var) = ((unsigned long long int) _hi << 32) | _lo; }) - -/* The funny business for 32-bit mode is not required here. */ -# undef HP_TIMING_ACCUM -# define HP_TIMING_ACCUM(Sum, Diff) \ - do { \ - hp_timing_t __diff = (Diff) - GLRO(dl_hp_timing_overhead); \ - __asm__ __volatile__ ("lock; addq %1, %0" \ - : "=m" (Sum) : "r" (__diff), "m" (Sum)); \ - } while (0) +# include #endif /* hp-timing.h */