Bypass GOT/PLT for __ros_syscall within libc
authorAndrew Waterman <waterman@cs.berkeley.edu>
Tue, 23 Apr 2013 06:35:18 +0000 (23:35 -0700)
committerAndrew Waterman <waterman@cs.berkeley.edu>
Tue, 23 Apr 2013 06:35:18 +0000 (23:35 -0700)
Bypassing the global offset table removes one level of indirection in the
syscall path.  On RISC-V, a call via the GOT is three instructions, including
a load, whereas a direct call is a single instruction with no data memory
access.  The situation in x86 is analogous, though it's the PLT and
instruction cache that are bypassed, rather than the GOT and data cache.
(FWIW, the difference is due to self-modifying code being cheap on x86.)

In general, libc_hidden_proto/libc_hidden_def have this effect, but they
should only be used when interposition isn't necessary (e.g. you can't use
LD_PRELOAD to override function definitions if the PLT is bypassed).

tools/compilers/gcc-glibc/glibc-2.14.1-ros/sysdeps/ros/sys/syscall.h
tools/compilers/gcc-glibc/glibc-2.14.1-ros/sysdeps/ros/syscall.c

index d30db33..64ff570 100644 (file)
@@ -31,6 +31,12 @@ long __ros_syscall(unsigned int _num, long _a0, long _a1, long _a2, long _a3,
 long __ros_syscall_errno(unsigned int _num, long _a0, long _a1, long _a2,
                          long _a3, long _a4, long _a5);
 
+/* Bypass PLT when invoked from within libc */
+#ifdef libc_hidden_proto
+libc_hidden_proto(__ros_syscall)
+libc_hidden_proto(__ros_syscall_errno)
+#endif
+
 /**************** Additional syscall support ****************/
 /* Simple ev_q that routes notifs to vcore0's public mbox.  This is used by the
  * default scp_syscall, but can also be used for signals or other basic
index 51a9b35..9251221 100644 (file)
@@ -126,6 +126,7 @@ long __ros_syscall(unsigned int _num, long _a0, long _a1, long _a2, long _a3,
                *errno_loc = sysc.err;
        return sysc.retval;
 }
+libc_hidden_def(__ros_syscall)
 
 /* This version knows about errno and will handle it. */
 long __ros_syscall_errno(unsigned int _num, long _a0, long _a1, long _a2,
@@ -137,6 +138,7 @@ long __ros_syscall_errno(unsigned int _num, long _a0, long _a1, long _a2,
                errno = sysc.err;
        return sysc.retval;
 }
+libc_hidden_def(__ros_syscall_errno)
 
 long int syscall(long int num, ...)
 {