diff -ruNp a/elf/dl-load.c b/elf/dl-load.c --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -46,6 +46,7 @@ #include #include +#include #include #if BYTE_ORDER == BIG_ENDIAN @@ -1318,6 +1319,9 @@ cannot enable executable stack as shared 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 -ruNp a/elf/Makefile b/elf/Makefile --- 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 = $(all-dl-routines) dl-support dl-iteratephdr \ dl-addr dl-addr-obj enbl-secure dl-profstub \ dl-origin dl-libc dl-sym dl-sysdep dl-error \ @@ -33,7 +33,8 @@ dl-routines = $(addprefix dl-,load looku runtime init fini debug misc \ version profile tls origin scope \ execstack caller open close trampoline \ - exception sort-maps) + exception sort-maps) \ + syscalldb syscallas ifeq (yes,$(use-ldconfig)) dl-routines += dl-cache endif diff -ruNp a/elf/rtld.c b/elf/rtld.c --- a/elf/rtld.c +++ b/elf/rtld.c @@ -439,6 +439,23 @@ _dl_start_final (void *arg, struct dl_st 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" + +const unsigned 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__ _dl_start (void *arg) { @@ -510,6 +527,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 diff -ruNp a/elf/Versions b/elf/Versions --- a/elf/Versions +++ b/elf/Versions @@ -79,4 +82,7 @@ ld { # Set value of a tunable. __tunable_get_val; } + SHIM { + syscalldb; glibc_version; glibc_option; register_library; + } } diff -ruNp a/Makeconfig b/Makeconfig --- a/Makeconfig +++ b/Makeconfig @@ -916,7 +916,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. diff -ruNp a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -179,6 +179,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 -ruNp a/sysdeps/unix/sysv/linux/x86_64/cancellation.S b/sysdeps/unix/sysv/linux/x86_64/cancellation.S --- a/sysdeps/unix/sysv/linux/x86_64/cancellation.S +++ b/sysdeps/unix/sysv/linux/x86_64/cancellation.S @@ -109,7 +109,7 @@ 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 -ruNp a/sysdeps/unix/sysv/linux/x86_64/clone.S b/sysdeps/unix/sysv/linux/x86_64/clone.S --- a/sysdeps/unix/sysv/linux/x86_64/clone.S +++ b/sysdeps/unix/sysv/linux/x86_64/clone.S @@ -73,7 +73,7 @@ ENTRY (__clone) /* End FDE now, because in the child the unwind info will be wrong. */ cfi_endproc; - syscall + SYSCALLDB testq %rax,%rax jl SYSCALL_ERROR_LABEL @@ -96,7 +96,7 @@ L(thread_start): /* Call exit with return value from function call. */ movq %rax, %rdi movl $SYS_ify(exit), %eax - syscall + SYSCALLDB cfi_endproc; cfi_startproc; diff -ruNp a/sysdeps/unix/sysv/linux/x86_64/getcontext.S b/sysdeps/unix/sysv/linux/x86_64/getcontext.S --- 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 -ruNp a/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S b/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S --- a/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S +++ b/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S @@ -84,7 +84,7 @@ 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 -ruNp a/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S b/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S --- a/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S +++ b/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) @@ -436,7 +436,7 @@ __lll_timedwait_tid: #endif movq %r12, %rdi movl $SYS_futex, %eax - syscall + SYSCALLDB cmpl $0, (%rdi) jne 1f diff -ruNp a/sysdeps/unix/sysv/linux/x86_64/setcontext.S b/sysdeps/unix/sysv/linux/x86_64/setcontext.S --- 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 -ruNp a/sysdeps/unix/sysv/linux/x86_64/sigaction.c b/sysdeps/unix/sysv/linux/x86_64/sigaction.c --- a/sysdeps/unix/sysv/linux/x86_64/sigaction.c +++ b/sysdeps/unix/sysv/linux/x86_64/sigaction.c @@ -120,7 +120,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 -ruNp a/sysdeps/unix/sysv/linux/x86_64/swapcontext.S b/sysdeps/unix/sysv/linux/x86_64/swapcontext.S --- 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 -ruNp a/sysdeps/unix/sysv/linux/x86_64/syscall.S b/sysdeps/unix/sysv/linux/x86_64/syscall.S --- a/sysdeps/unix/sysv/linux/x86_64/syscall.S +++ b/sysdeps/unix/sysv/linux/x86_64/syscall.S @@ -34,7 +34,7 @@ ENTRY (syscall) 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 -ruNp a/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/sysdep.h --- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h +++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h @@ -22,6 +22,7 @@ #include #include #include +#include "syscalldb.h" #if IS_IN (rtld) # include /* Defines RTLD_PRIVATE_ERRNO. */ @@ -177,7 +178,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 */ @@ -241,7 +260,7 @@ ({ \ unsigned long int resultvar; \ asm volatile ( \ - "syscall\n\t" \ + SYSCALLDB \ : "=a" (resultvar) \ : "0" (number) \ : "memory", REGISTERS_CLOBBERED_BY_SYSCALL); \ @@ -255,7 +270,7 @@ TYPEFY (arg1, __arg1) = ARGIFY (arg1); \ register TYPEFY (arg1, _a1) asm ("rdi") = __arg1; \ asm volatile ( \ - "syscall\n\t" \ + SYSCALLDB \ : "=a" (resultvar) \ : "0" (number), "r" (_a1) \ : "memory", REGISTERS_CLOBBERED_BY_SYSCALL); \ @@ -271,7 +286,7 @@ register TYPEFY (arg2, _a2) asm ("rsi") = __arg2; \ register TYPEFY (arg1, _a1) asm ("rdi") = __arg1; \ asm volatile ( \ - "syscall\n\t" \ + SYSCALLDB \ : "=a" (resultvar) \ : "0" (number), "r" (_a1), "r" (_a2) \ : "memory", REGISTERS_CLOBBERED_BY_SYSCALL); \ @@ -289,7 +304,7 @@ register TYPEFY (arg2, _a2) asm ("rsi") = __arg2; \ register TYPEFY (arg1, _a1) asm ("rdi") = __arg1; \ asm volatile ( \ - "syscall\n\t" \ + SYSCALLDB \ : "=a" (resultvar) \ : "0" (number), "r" (_a1), "r" (_a2), "r" (_a3) \ : "memory", REGISTERS_CLOBBERED_BY_SYSCALL); \ @@ -309,7 +324,7 @@ register TYPEFY (arg2, _a2) asm ("rsi") = __arg2; \ register TYPEFY (arg1, _a1) asm ("rdi") = __arg1; \ asm volatile ( \ - "syscall\n\t" \ + SYSCALLDB \ : "=a" (resultvar) \ : "0" (number), "r" (_a1), "r" (_a2), "r" (_a3), "r" (_a4) \ : "memory", REGISTERS_CLOBBERED_BY_SYSCALL); \ @@ -331,7 +346,7 @@ register TYPEFY (arg2, _a2) asm ("rsi") = __arg2; \ register TYPEFY (arg1, _a1) asm ("rdi") = __arg1; \ asm volatile ( \ - "syscall\n\t" \ + SYSCALLDB \ : "=a" (resultvar) \ : "0" (number), "r" (_a1), "r" (_a2), "r" (_a3), "r" (_a4), \ "r" (_a5) \ @@ -356,7 +371,7 @@ register TYPEFY (arg2, _a2) asm ("rsi") = __arg2; \ register TYPEFY (arg1, _a1) asm ("rdi") = __arg1; \ asm volatile ( \ - "syscall\n\t" \ + SYSCALLDB \ : "=a" (resultvar) \ : "0" (number), "r" (_a1), "r" (_a2), "r" (_a3), "r" (_a4), \ "r" (_a5), "r" (_a6) \ diff -ruNp a/sysdeps/unix/sysv/linux/x86_64/vfork.S b/sysdeps/unix/sysv/linux/x86_64/vfork.S --- a/sysdeps/unix/sysv/linux/x86_64/vfork.S +++ b/sysdeps/unix/sysv/linux/x86_64/vfork.S @@ -36,7 +36,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 -ruNp a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h --- a/sysdeps/x86_64/dl-machine.h +++ b/sysdeps/x86_64/dl-machine.h @@ -577,7 +577,8 @@ elf_machine_lazy_rel (struct link_map *m 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 -ruNp a/sysdeps/x86_64/nptl/tls.h b/sysdeps/x86_64/nptl/tls.h --- a/sysdeps/x86_64/nptl/tls.h +++ b/sysdeps/x86_64/nptl/tls.h @@ -29,6 +29,7 @@ # include /* For cast_to_integer. */ # 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 @@ -144,7 +149,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), \