Compare commits
	
		
			66 Commits
		
	
	
		
			jb-mr2.0-r
			...
			tools_r22
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					ff220f7003 | ||
| 
						 | 
					63dd03cced | ||
| 
						 | 
					b9256adab3 | ||
| 
						 | 
					52171b9bdc | ||
| 
						 | 
					d541ba1719 | ||
| 
						 | 
					1c462b7a04 | ||
| 
						 | 
					b01f7afd5f | ||
| 
						 | 
					532d6f09b1 | ||
| 
						 | 
					e4ac8feb58 | ||
| 
						 | 
					4f40e511b0 | ||
| 
						 | 
					5e3b502b6b | ||
| 
						 | 
					277226bf43 | ||
| 
						 | 
					8c00c91aa0 | ||
| 
						 | 
					80541922e3 | ||
| 
						 | 
					bee0ab16e4 | ||
| 
						 | 
					3b2e6bc9ac | ||
| 
						 | 
					c46871302e | ||
| 
						 | 
					9020fd503c | ||
| 
						 | 
					b94b2851d7 | ||
| 
						 | 
					78d6d9888c | ||
| 
						 | 
					382a775378 | ||
| 
						 | 
					1aae9bd170 | ||
| 
						 | 
					c6dc62f09c | ||
| 
						 | 
					e66ad7809e | ||
| 
						 | 
					f7153fd13f | ||
| 
						 | 
					9ff1ffd805 | ||
| 
						 | 
					e7aaad8b83 | ||
| 
						 | 
					5f28fde8ae | ||
| 
						 | 
					8d3e91d4f8 | ||
| 
						 | 
					e8f46e8edd | ||
| 
						 | 
					87efcd2e63 | ||
| 
						 | 
					85aeb49144 | ||
| 
						 | 
					c705daa0a2 | ||
| 
						 | 
					21da42ea91 | ||
| 
						 | 
					2c60c18c50 | ||
| 
						 | 
					bda2fb5efa | ||
| 
						 | 
					676e66db25 | ||
| 
						 | 
					2379088a90 | ||
| 
						 | 
					70e0bd3a44 | ||
| 
						 | 
					f8dff7d449 | ||
| 
						 | 
					8c181aa8fe | ||
| 
						 | 
					516a897053 | ||
| 
						 | 
					b3c8c4d865 | ||
| 
						 | 
					796cbe249b | ||
| 
						 | 
					ea489745dc | ||
| 
						 | 
					0b25f633a2 | ||
| 
						 | 
					ed36d95fac | ||
| 
						 | 
					6b05c8e280 | ||
| 
						 | 
					b632857a50 | ||
| 
						 | 
					4ca685e36e | ||
| 
						 | 
					fc76c7d394 | ||
| 
						 | 
					bf0d1ad72b | ||
| 
						 | 
					68fd78efa0 | ||
| 
						 | 
					185ce72d00 | ||
| 
						 | 
					240fb8623b | ||
| 
						 | 
					0d787c1fa1 | ||
| 
						 | 
					014c75c78b | ||
| 
						 | 
					8baa929d5d | ||
| 
						 | 
					14c840df90 | ||
| 
						 | 
					a51916b58b | ||
| 
						 | 
					162b4411fc | ||
| 
						 | 
					4ace92c62a | ||
| 
						 | 
					7a29f404e1 | ||
| 
						 | 
					378b0e1ea2 | ||
| 
						 | 
					6bb17dfad3 | ||
| 
						 | 
					cfa089df23 | 
@@ -15,58 +15,29 @@ libc_common_src_files := \
 | 
			
		||||
	unistd/system.c \
 | 
			
		||||
	unistd/time.c \
 | 
			
		||||
	stdio/asprintf.c \
 | 
			
		||||
	stdio/clrerr.c \
 | 
			
		||||
	stdio/fclose.c \
 | 
			
		||||
	stdio/fdopen.c \
 | 
			
		||||
	stdio/feof.c \
 | 
			
		||||
	stdio/ferror.c \
 | 
			
		||||
	stdio/fflush.c \
 | 
			
		||||
	stdio/fgetc.c \
 | 
			
		||||
	stdio/fgetln.c \
 | 
			
		||||
	stdio/fgetpos.c \
 | 
			
		||||
	stdio/fgets.c \
 | 
			
		||||
	stdio/fileno.c \
 | 
			
		||||
	stdio/findfp.c \
 | 
			
		||||
	stdio/flags.c \
 | 
			
		||||
	stdio/fopen.c \
 | 
			
		||||
	stdio/fprintf.c \
 | 
			
		||||
	stdio/fpurge.c \
 | 
			
		||||
	stdio/fputc.c \
 | 
			
		||||
	stdio/fputs.c \
 | 
			
		||||
	stdio/fread.c \
 | 
			
		||||
	stdio/freopen.c \
 | 
			
		||||
	stdio/fscanf.c \
 | 
			
		||||
	stdio/fseek.c \
 | 
			
		||||
	stdio/fsetpos.c \
 | 
			
		||||
	stdio/ftell.c \
 | 
			
		||||
	stdio/funopen.c \
 | 
			
		||||
	stdio/fvwrite.c \
 | 
			
		||||
	stdio/fwalk.c \
 | 
			
		||||
	stdio/fwrite.c \
 | 
			
		||||
	stdio/getc.c \
 | 
			
		||||
	stdio/getchar.c \
 | 
			
		||||
	stdio/gets.c \
 | 
			
		||||
	stdio/makebuf.c \
 | 
			
		||||
	stdio/mktemp.c \
 | 
			
		||||
	stdio/printf.c \
 | 
			
		||||
	stdio/putc.c \
 | 
			
		||||
	stdio/putchar.c \
 | 
			
		||||
	stdio/puts.c \
 | 
			
		||||
	stdio/putw.c \
 | 
			
		||||
	stdio/refill.c \
 | 
			
		||||
	stdio/remove.c \
 | 
			
		||||
	stdio/rewind.c \
 | 
			
		||||
	stdio/rget.c \
 | 
			
		||||
	stdio/scanf.c \
 | 
			
		||||
	stdio/setbuf.c \
 | 
			
		||||
	stdio/setbuffer.c \
 | 
			
		||||
	stdio/setvbuf.c \
 | 
			
		||||
	stdio/snprintf.c\
 | 
			
		||||
	stdio/sprintf.c \
 | 
			
		||||
	stdio/sscanf.c \
 | 
			
		||||
	stdio/stdio.c \
 | 
			
		||||
	stdio/tempnam.c \
 | 
			
		||||
	stdio/tmpnam.c \
 | 
			
		||||
	stdio/ungetc.c \
 | 
			
		||||
	stdio/vasprintf.c \
 | 
			
		||||
	stdio/vfprintf.c \
 | 
			
		||||
@@ -77,13 +48,11 @@ libc_common_src_files := \
 | 
			
		||||
	stdio/vscanf.c \
 | 
			
		||||
	stdio/vsscanf.c \
 | 
			
		||||
	stdio/wbuf.c \
 | 
			
		||||
	stdio/wsetup.c \
 | 
			
		||||
	stdlib/atexit.c \
 | 
			
		||||
	stdlib/ctype_.c \
 | 
			
		||||
	stdlib/exit.c \
 | 
			
		||||
	stdlib/getenv.c \
 | 
			
		||||
	stdlib/putenv.c \
 | 
			
		||||
	stdlib/qsort.c \
 | 
			
		||||
	stdlib/setenv.c \
 | 
			
		||||
	stdlib/strtod.c \
 | 
			
		||||
	stdlib/strtoimax.c \
 | 
			
		||||
@@ -97,7 +66,6 @@ libc_common_src_files := \
 | 
			
		||||
	string/index.c \
 | 
			
		||||
	string/strcasecmp.c \
 | 
			
		||||
	string/strcat.c \
 | 
			
		||||
	string/strchr.c \
 | 
			
		||||
	string/strcspn.c \
 | 
			
		||||
	string/strdup.c \
 | 
			
		||||
	string/strlcat.c \
 | 
			
		||||
@@ -170,7 +138,6 @@ libc_common_src_files := \
 | 
			
		||||
	bionic/recv.c \
 | 
			
		||||
	bionic/sched_cpualloc.c \
 | 
			
		||||
	bionic/sched_cpucount.c \
 | 
			
		||||
	bionic/sched_getaffinity.c \
 | 
			
		||||
	bionic/sched_getcpu.c \
 | 
			
		||||
	bionic/semaphore.c \
 | 
			
		||||
	bionic/send.c \
 | 
			
		||||
@@ -238,7 +205,8 @@ libc_bionic_src_files := \
 | 
			
		||||
    bionic/brk.cpp \
 | 
			
		||||
    bionic/dirent.cpp \
 | 
			
		||||
    bionic/__errno.c \
 | 
			
		||||
    bionic/eventfd.cpp \
 | 
			
		||||
    bionic/eventfd_read.cpp \
 | 
			
		||||
    bionic/eventfd_write.cpp \
 | 
			
		||||
    bionic/__fgets_chk.cpp \
 | 
			
		||||
    bionic/getauxval.cpp \
 | 
			
		||||
    bionic/getcwd.cpp \
 | 
			
		||||
@@ -263,11 +231,13 @@ libc_bionic_src_files := \
 | 
			
		||||
    bionic/raise.cpp \
 | 
			
		||||
    bionic/sbrk.cpp \
 | 
			
		||||
    bionic/scandir.cpp \
 | 
			
		||||
    bionic/sched_getaffinity.cpp \
 | 
			
		||||
    bionic/__set_errno.cpp \
 | 
			
		||||
    bionic/setlocale.cpp \
 | 
			
		||||
    bionic/signalfd.cpp \
 | 
			
		||||
    bionic/sigwait.cpp \
 | 
			
		||||
    bionic/__strcat_chk.cpp \
 | 
			
		||||
    bionic/strchr.cpp \
 | 
			
		||||
    bionic/__strcpy_chk.cpp \
 | 
			
		||||
    bionic/strerror.cpp \
 | 
			
		||||
    bionic/strerror_r.cpp \
 | 
			
		||||
@@ -288,6 +258,37 @@ libc_bionic_src_files := \
 | 
			
		||||
    bionic/wchar.cpp \
 | 
			
		||||
 | 
			
		||||
libc_upstream_freebsd_src_files := \
 | 
			
		||||
    upstream-freebsd/lib/libc/stdio/clrerr.c \
 | 
			
		||||
    upstream-freebsd/lib/libc/stdio/fclose.c \
 | 
			
		||||
    upstream-freebsd/lib/libc/stdio/fdopen.c \
 | 
			
		||||
    upstream-freebsd/lib/libc/stdio/feof.c \
 | 
			
		||||
    upstream-freebsd/lib/libc/stdio/ferror.c \
 | 
			
		||||
    upstream-freebsd/lib/libc/stdio/fgetln.c \
 | 
			
		||||
    upstream-freebsd/lib/libc/stdio/fgetpos.c \
 | 
			
		||||
    upstream-freebsd/lib/libc/stdio/fgets.c \
 | 
			
		||||
    upstream-freebsd/lib/libc/stdio/fileno.c \
 | 
			
		||||
    upstream-freebsd/lib/libc/stdio/flags.c \
 | 
			
		||||
    upstream-freebsd/lib/libc/stdio/fopen.c \
 | 
			
		||||
    upstream-freebsd/lib/libc/stdio/fpurge.c \
 | 
			
		||||
    upstream-freebsd/lib/libc/stdio/fputs.c \
 | 
			
		||||
    upstream-freebsd/lib/libc/stdio/fsetpos.c \
 | 
			
		||||
    upstream-freebsd/lib/libc/stdio/funopen.c \
 | 
			
		||||
    upstream-freebsd/lib/libc/stdio/fwalk.c \
 | 
			
		||||
    upstream-freebsd/lib/libc/stdio/fwrite.c \
 | 
			
		||||
    upstream-freebsd/lib/libc/stdio/getc.c \
 | 
			
		||||
    upstream-freebsd/lib/libc/stdio/getchar.c \
 | 
			
		||||
    upstream-freebsd/lib/libc/stdio/putc.c \
 | 
			
		||||
    upstream-freebsd/lib/libc/stdio/putchar.c \
 | 
			
		||||
    upstream-freebsd/lib/libc/stdio/puts.c \
 | 
			
		||||
    upstream-freebsd/lib/libc/stdio/putw.c \
 | 
			
		||||
    upstream-freebsd/lib/libc/stdio/remove.c \
 | 
			
		||||
    upstream-freebsd/lib/libc/stdio/rget.c \
 | 
			
		||||
    upstream-freebsd/lib/libc/stdio/setbuf.c \
 | 
			
		||||
    upstream-freebsd/lib/libc/stdio/setbuffer.c \
 | 
			
		||||
    upstream-freebsd/lib/libc/stdio/tempnam.c \
 | 
			
		||||
    upstream-freebsd/lib/libc/stdio/tmpnam.c \
 | 
			
		||||
    upstream-freebsd/lib/libc/stdio/wsetup.c \
 | 
			
		||||
    upstream-freebsd/lib/libc/stdlib/qsort.c \
 | 
			
		||||
    upstream-freebsd/lib/libc/stdlib/realpath.c \
 | 
			
		||||
    upstream-freebsd/lib/libc/string/wcpcpy.c \
 | 
			
		||||
    upstream-freebsd/lib/libc/string/wcpncpy.c \
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,11 @@
 | 
			
		||||
# this file is used to list all the syscalls that will be supported by
 | 
			
		||||
# the Bionic C library. It is used to automatically generate the syscall
 | 
			
		||||
# stubs, the list of syscall constants (__NR_xxxx) and the content of <linux/_unistd.h>
 | 
			
		||||
# This file is used to automatically generate bionic's the system calls stubs.
 | 
			
		||||
#
 | 
			
		||||
# each non comment line has the following format:
 | 
			
		||||
# Each non comment line has the following format:
 | 
			
		||||
#
 | 
			
		||||
# return_type    func_name[:syscall_name[:call_id]]([parameter_list])  (syscall_number|"stub")
 | 
			
		||||
# return_type    func_name[:syscall_name[:call_id]]([parameter_list])  (1|-1|"stub")
 | 
			
		||||
#
 | 
			
		||||
# note that:
 | 
			
		||||
#      - syscall_name correspond to the name of the syscall, which may differ from
 | 
			
		||||
# Note that:
 | 
			
		||||
#      - syscall_name corresponds to the name of the syscall, which may differ from
 | 
			
		||||
#        the exported function name (example: the exit syscall is implemented by the _exit()
 | 
			
		||||
#        function, which is not the same as the standard C exit() function which calls it)
 | 
			
		||||
#        The call_id parameter, given that func_name and syscall_name have
 | 
			
		||||
@@ -18,302 +16,306 @@
 | 
			
		||||
#      - each parameter type is assumed to be stored on 32 bits, there is no plan to support
 | 
			
		||||
#        64-bit architectures at the moment
 | 
			
		||||
#
 | 
			
		||||
#      - it there is "stub" instead of a syscall number, the tool will not generate any
 | 
			
		||||
#        assembler template for the syscall; it's up to the bionic implementation to provide
 | 
			
		||||
#        a relevant C stub
 | 
			
		||||
#      - the final field can be "1", meaning: generate a stub for each architecture,
 | 
			
		||||
#        taking the constants from the kernel header files.
 | 
			
		||||
#
 | 
			
		||||
#      - additionally, if the syscall number is different amoung ARM, and x86, MIPS use:
 | 
			
		||||
#        return_type funcname[:syscall_name](parameters) arm_number,x86_number,mips_number
 | 
			
		||||
#      - the final field can be "stub" meaning: do not generate any stubs ---
 | 
			
		||||
#        in this case, a hand-written custom stub must be provided.
 | 
			
		||||
#        TODO: replace this with something like "custom" or "none", or remove
 | 
			
		||||
#        it entirely.
 | 
			
		||||
#
 | 
			
		||||
#      - the final field can be a three-element list of 1s and -1 meaning:
 | 
			
		||||
#        this system call is only available on some of the architectures (1),
 | 
			
		||||
#        and no stub should be generated for those architectures marked with -1.
 | 
			
		||||
#        the order is arm,x86,mips.
 | 
			
		||||
#        TODO: replace this with something more readable like "-arm,-mips" (meaning x86 only).
 | 
			
		||||
#
 | 
			
		||||
# This file is processed by a python script named gensyscalls.py.
 | 
			
		||||
#
 | 
			
		||||
# The checksyscalls.py script can check that the syscall numbers here are
 | 
			
		||||
# correct by comparing them to the numbers in the Linux kernel headers.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
# process management
 | 
			
		||||
void    _exit:exit_group (int)      248,252,246
 | 
			
		||||
void    _exit:exit_group (int)      1
 | 
			
		||||
void    _exit_thread:exit (int)     1
 | 
			
		||||
pid_t   __fork:fork (void)           2
 | 
			
		||||
pid_t   _waitpid:waitpid (pid_t, int*, int, struct rusage*)   -1,7,7
 | 
			
		||||
int     __waitid:waitid(int, pid_t, struct siginfo_t*, int,void*)          280,284,278
 | 
			
		||||
pid_t   wait4(pid_t pid, int *status, int options, struct rusage *rusage)   114
 | 
			
		||||
pid_t   __fork:fork (void)           1
 | 
			
		||||
pid_t   _waitpid:waitpid (pid_t, int*, int, struct rusage*)   -1,1,1
 | 
			
		||||
int     __waitid:waitid(int, pid_t, struct siginfo_t*, int,void*)          1
 | 
			
		||||
pid_t   wait4(pid_t pid, int *status, int options, struct rusage *rusage)   1
 | 
			
		||||
 | 
			
		||||
# NOTE: this system call is never called directly, but we list it there
 | 
			
		||||
#       to have __NR_clone properly defined.
 | 
			
		||||
#
 | 
			
		||||
pid_t   __sys_clone:clone (int, void*, int*, void*, int*) 120
 | 
			
		||||
pid_t   __sys_clone:clone (int, void*, int*, void*, int*) 1
 | 
			
		||||
 | 
			
		||||
int     execve (const char*, char* const*, char* const*)  11
 | 
			
		||||
int     execve (const char*, char* const*, char* const*)  1
 | 
			
		||||
 | 
			
		||||
int     __setuid:setuid32 (uid_t)    213,213,-1
 | 
			
		||||
int     __setuid:setuid (uid_t)   -1,-1,23
 | 
			
		||||
uid_t   getuid:getuid32 ()         199,199,-1
 | 
			
		||||
uid_t   getuid:getuid ()           -1,-1,24
 | 
			
		||||
gid_t   getgid:getgid32 ()         200,200,-1
 | 
			
		||||
gid_t   getgid:getgid ()           -1,-1,47
 | 
			
		||||
uid_t   geteuid:geteuid32 ()       201,201,-1
 | 
			
		||||
uid_t   geteuid:geteuid ()         -1,-1,49
 | 
			
		||||
gid_t   getegid:getegid32 ()       202,202,-1
 | 
			
		||||
gid_t   getegid:getegid ()         -1,-1,50
 | 
			
		||||
uid_t   getresuid:getresuid32 (uid_t *ruid, uid_t *euid, uid_t *suid)   209,209,-1
 | 
			
		||||
uid_t   getresuid:getresuid (uid_t *ruid, uid_t *euid, uid_t *suid)     -1,-1,186
 | 
			
		||||
gid_t   getresgid:getresgid32 (gid_t *rgid, gid_t *egid, gid_t *sgid)   211,211,-1
 | 
			
		||||
gid_t   getresgid:getresgid (gid_t *rgid, gid_t *egid, gid_t *sgid)     -1,-1,191
 | 
			
		||||
pid_t   gettid()                   224,224,222
 | 
			
		||||
ssize_t readahead(int, off64_t, size_t)     225,225,223
 | 
			
		||||
int     getgroups:getgroups32(int, gid_t *)    205,205,-1
 | 
			
		||||
int     getgroups:getgroups(int, gid_t *)      -1,-1,80
 | 
			
		||||
pid_t   getpgid(pid_t)             132
 | 
			
		||||
pid_t   getppid()                  64
 | 
			
		||||
pid_t   getsid(pid_t)              147,147,151
 | 
			
		||||
pid_t   setsid()                   66
 | 
			
		||||
int     setgid:setgid32(gid_t)     214,214,-1
 | 
			
		||||
int     setgid:setgid(gid_t)       -1,-1,46
 | 
			
		||||
int     __setuid:setuid32 (uid_t)    1,1,-1
 | 
			
		||||
int     __setuid:setuid (uid_t)   -1,-1,1
 | 
			
		||||
uid_t   getuid:getuid32 ()         1,1,-1
 | 
			
		||||
uid_t   getuid:getuid ()           -1,-1,1
 | 
			
		||||
gid_t   getgid:getgid32 ()         1,1,-1
 | 
			
		||||
gid_t   getgid:getgid ()           -1,-1,1
 | 
			
		||||
uid_t   geteuid:geteuid32 ()       1,1,-1
 | 
			
		||||
uid_t   geteuid:geteuid ()         -1,-1,1
 | 
			
		||||
gid_t   getegid:getegid32 ()       1,1,-1
 | 
			
		||||
gid_t   getegid:getegid ()         -1,-1,1
 | 
			
		||||
uid_t   getresuid:getresuid32 (uid_t *ruid, uid_t *euid, uid_t *suid)   1,1,-1
 | 
			
		||||
uid_t   getresuid:getresuid (uid_t *ruid, uid_t *euid, uid_t *suid)     -1,-1,1
 | 
			
		||||
gid_t   getresgid:getresgid32 (gid_t *rgid, gid_t *egid, gid_t *sgid)   1,1,-1
 | 
			
		||||
gid_t   getresgid:getresgid (gid_t *rgid, gid_t *egid, gid_t *sgid)     -1,-1,1
 | 
			
		||||
pid_t   gettid()                   1
 | 
			
		||||
ssize_t readahead(int, off64_t, size_t)     1
 | 
			
		||||
int     getgroups:getgroups32(int, gid_t *)    1,1,-1
 | 
			
		||||
int     getgroups:getgroups(int, gid_t *)      -1,-1,1
 | 
			
		||||
pid_t   getpgid(pid_t)             1
 | 
			
		||||
pid_t   getppid()                  1
 | 
			
		||||
pid_t   getsid(pid_t)              1
 | 
			
		||||
pid_t   setsid()                   1
 | 
			
		||||
int     setgid:setgid32(gid_t)     1,1,-1
 | 
			
		||||
int     setgid:setgid(gid_t)       -1,-1,1
 | 
			
		||||
int     seteuid:seteuid32(uid_t)   stub
 | 
			
		||||
int     __setreuid:setreuid32(uid_t, uid_t)   203,203,-1
 | 
			
		||||
int     __setreuid:setreuid(uid_t, uid_t)     -1,-1,70
 | 
			
		||||
int     __setresuid:setresuid32(uid_t, uid_t, uid_t)   208,208,-1
 | 
			
		||||
int     __setresuid:setresuid(uid_t, uid_t, uid_t)     -1,-1,185
 | 
			
		||||
int     setresgid:setresgid32(gid_t, gid_t, gid_t)   210,210,-1
 | 
			
		||||
int     setresgid:setresgid(gid_t, gid_t, gid_t)     -1,-1,190
 | 
			
		||||
void*   __brk:brk(void*)           45
 | 
			
		||||
int     __setreuid:setreuid32(uid_t, uid_t)   1,1,-1
 | 
			
		||||
int     __setreuid:setreuid(uid_t, uid_t)     -1,-1,1
 | 
			
		||||
int     __setresuid:setresuid32(uid_t, uid_t, uid_t)   1,1,-1
 | 
			
		||||
int     __setresuid:setresuid(uid_t, uid_t, uid_t)     -1,-1,1
 | 
			
		||||
int     setresgid:setresgid32(gid_t, gid_t, gid_t)   1,1,-1
 | 
			
		||||
int     setresgid:setresgid(gid_t, gid_t, gid_t)     -1,-1,1
 | 
			
		||||
void*   __brk:brk(void*)           1
 | 
			
		||||
# see comments in arch-arm/bionic/kill.S to understand why we don't generate an ARM stub for kill/tkill
 | 
			
		||||
int     kill(pid_t, int)           -1,37,37
 | 
			
		||||
int     tkill(pid_t tid, int sig)  -1,238,236
 | 
			
		||||
int     tgkill(pid_t tgid, pid_t tid, int sig)  -1,270,266
 | 
			
		||||
int     __ptrace:ptrace(int request, int pid, void* addr, void* data)  26
 | 
			
		||||
int     __set_thread_area:set_thread_area(void*  user_desc)  -1,243,283
 | 
			
		||||
int     __getpriority:getpriority(int, int)  96
 | 
			
		||||
int     setpriority(int, int, int)   97
 | 
			
		||||
int     setrlimit(int resource, const struct rlimit *rlp)  75
 | 
			
		||||
int     getrlimit:ugetrlimit(int resource, struct rlimit *rlp)  191,191,-1
 | 
			
		||||
int     getrlimit:getrlimit(int resource, struct rlimit *rlp)  -1,-1,76
 | 
			
		||||
int     getrusage(int who, struct rusage*  r_usage)  77
 | 
			
		||||
int     setgroups:setgroups32(int, const gid_t *)   206,206,-1
 | 
			
		||||
int     setgroups:setgroups(int, const gid_t *)     -1,-1,81
 | 
			
		||||
int     kill(pid_t, int)           -1,1,1
 | 
			
		||||
int     tkill(pid_t tid, int sig)  -1,1,1
 | 
			
		||||
int     tgkill(pid_t tgid, pid_t tid, int sig)  -1,1,1
 | 
			
		||||
int     __ptrace:ptrace(int request, int pid, void* addr, void* data)  1
 | 
			
		||||
int     __set_thread_area:set_thread_area(void*  user_desc)  -1,1,1
 | 
			
		||||
int     __getpriority:getpriority(int, int)  1
 | 
			
		||||
int     setpriority(int, int, int)   1
 | 
			
		||||
int     setrlimit(int resource, const struct rlimit *rlp)  1
 | 
			
		||||
int     getrlimit:ugetrlimit(int resource, struct rlimit *rlp)  1,1,-1
 | 
			
		||||
int     getrlimit:getrlimit(int resource, struct rlimit *rlp)  -1,-1,1
 | 
			
		||||
int     getrusage(int who, struct rusage*  r_usage)  1
 | 
			
		||||
int     setgroups:setgroups32(int, const gid_t *)   1,1,-1
 | 
			
		||||
int     setgroups:setgroups(int, const gid_t *)     -1,-1,1
 | 
			
		||||
pid_t   getpgrp(void)  stub
 | 
			
		||||
int     setpgid(pid_t, pid_t)  57
 | 
			
		||||
pid_t   vfork(void)  190,-1,-1
 | 
			
		||||
int     setregid:setregid32(gid_t, gid_t)  204,204,-1
 | 
			
		||||
int     setregid:setregid(gid_t, gid_t)    -1,-1,71
 | 
			
		||||
int     chroot(const char *)  61
 | 
			
		||||
int     setpgid(pid_t, pid_t)  1
 | 
			
		||||
pid_t   vfork(void)  1,-1,-1
 | 
			
		||||
int     setregid:setregid32(gid_t, gid_t)  1,1,-1
 | 
			
		||||
int     setregid:setregid(gid_t, gid_t)    -1,-1,1
 | 
			
		||||
int     chroot(const char *)  1
 | 
			
		||||
# IMPORTANT: Even though <sys/prctl.h> declares prctl(int,...), the syscall stub must take 6 arguments
 | 
			
		||||
#            to match the kernel implementation.
 | 
			
		||||
int     prctl(int option, unsigned int arg2, unsigned int arg3, unsigned int arg4, unsigned int arg5)  172,172,192
 | 
			
		||||
int     capget(cap_user_header_t header, cap_user_data_t data) 184,184,204
 | 
			
		||||
int     capset(cap_user_header_t header, const cap_user_data_t data) 185,185,205
 | 
			
		||||
int     sigaltstack(const stack_t*, stack_t*) 186,186,206
 | 
			
		||||
int     acct(const char*  filepath)  51
 | 
			
		||||
int     prctl(int option, unsigned int arg2, unsigned int arg3, unsigned int arg4, unsigned int arg5) 1
 | 
			
		||||
int     capget(cap_user_header_t header, cap_user_data_t data) 1
 | 
			
		||||
int     capset(cap_user_header_t header, const cap_user_data_t data) 1
 | 
			
		||||
int     sigaltstack(const stack_t*, stack_t*) 1
 | 
			
		||||
int     acct(const char*  filepath)  1
 | 
			
		||||
 | 
			
		||||
# file descriptors
 | 
			
		||||
ssize_t     read (int, void*, size_t)        3
 | 
			
		||||
ssize_t     write (int, const void*, size_t)       4
 | 
			
		||||
ssize_t     pread64 (int, void *, size_t, off64_t) 180,180,200
 | 
			
		||||
ssize_t     pwrite64 (int, void *, size_t, off64_t) 181,181,201
 | 
			
		||||
int         __open:open (const char*, int, mode_t)  5
 | 
			
		||||
int         __openat:openat (int, const char*, int, mode_t)  322,295,288
 | 
			
		||||
int         close (int)                      6
 | 
			
		||||
ssize_t     read (int, void*, size_t)        1
 | 
			
		||||
ssize_t     write (int, const void*, size_t)       1
 | 
			
		||||
ssize_t     pread64 (int, void *, size_t, off64_t) 1
 | 
			
		||||
ssize_t     pwrite64 (int, void *, size_t, off64_t) 1
 | 
			
		||||
int         __open:open (const char*, int, mode_t)  1
 | 
			
		||||
int         __openat:openat (int, const char*, int, mode_t) 1
 | 
			
		||||
int         close (int)                      1
 | 
			
		||||
int         creat(const char*, mode_t)       stub
 | 
			
		||||
off_t       lseek(int, off_t, int)           19
 | 
			
		||||
int         __llseek:_llseek (int, unsigned long, unsigned long, loff_t*, int)  140
 | 
			
		||||
pid_t       getpid ()    20
 | 
			
		||||
off_t       lseek(int, off_t, int)           1
 | 
			
		||||
int         __llseek:_llseek (int, unsigned long, unsigned long, loff_t*, int)  1
 | 
			
		||||
pid_t       getpid ()    1
 | 
			
		||||
void *      mmap(void *, size_t, int, int, int, long)  stub
 | 
			
		||||
void *      __mmap2:mmap2(void*, size_t, int, int, int, long)   192,192,210
 | 
			
		||||
int         munmap(void *, size_t)  91
 | 
			
		||||
void *      mremap(void *, size_t, size_t, unsigned long)  163,163,167
 | 
			
		||||
int         msync(const void *, size_t, int)    144
 | 
			
		||||
int         mprotect(const void *, size_t, int)  125
 | 
			
		||||
int         madvise(const void *, size_t, int)  220,219,218
 | 
			
		||||
int         mlock(const void *addr, size_t len)    150,150,154
 | 
			
		||||
int         munlock(const void *addr, size_t len)   151,151,155
 | 
			
		||||
int         mlockall(int flags)   152,152,156
 | 
			
		||||
int         munlockall()   153,153,157
 | 
			
		||||
int         mincore(void*  start, size_t  length, unsigned char*  vec)   219,218,217
 | 
			
		||||
int         __ioctl:ioctl(int, int, void *)  54
 | 
			
		||||
int         readv(int, const struct iovec *, int)   145
 | 
			
		||||
int         writev(int, const struct iovec *, int)  146
 | 
			
		||||
int         __fcntl:fcntl(int, int, void*)  55
 | 
			
		||||
int         flock(int, int)   143
 | 
			
		||||
int         fchmod(int, mode_t)  94
 | 
			
		||||
int         dup(int)  41
 | 
			
		||||
int         pipe(int *)  42,42,-1
 | 
			
		||||
int         pipe2(int *, int) 359,331,328
 | 
			
		||||
int         dup2(int, int)   63
 | 
			
		||||
int         select:_newselect(int, struct fd_set *, struct fd_set *, struct fd_set *, struct timeval *)  142
 | 
			
		||||
int         ftruncate(int, off_t)  93
 | 
			
		||||
int         ftruncate64(int, off64_t) 194,194,212
 | 
			
		||||
int         getdents:getdents64(unsigned int, struct dirent *, unsigned int)   217,220,219
 | 
			
		||||
int         fsync(int)  118
 | 
			
		||||
int         fdatasync(int) 148,148,152
 | 
			
		||||
int         fchown:fchown32(int, uid_t, gid_t)  207,207,-1
 | 
			
		||||
int         fchown:fchown(int, uid_t, gid_t)    -1,-1,95
 | 
			
		||||
void        sync(void)  36
 | 
			
		||||
int         __fcntl64:fcntl64(int, int, void *)  221,221,220
 | 
			
		||||
int         __fstatfs64:fstatfs64(int, size_t, struct statfs *)  267,269,256
 | 
			
		||||
ssize_t     sendfile(int out_fd, int in_fd, off_t *offset, size_t count)  187,187,207
 | 
			
		||||
int         fstatat:fstatat64(int dirfd, const char *path, struct stat *buf, int flags)   327,300,293
 | 
			
		||||
int         mkdirat(int dirfd, const char *pathname, mode_t mode)  323,296,289
 | 
			
		||||
int         fchownat(int dirfd, const char *path, uid_t owner, gid_t group, int flags)  325,298,291
 | 
			
		||||
int         fchmodat(int dirfd, const char *path, mode_t mode, int flags)  333,306,299
 | 
			
		||||
int         renameat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath)  329,302,295
 | 
			
		||||
int         fsetxattr(int, const char *, const void *, size_t, int) 228,228,226
 | 
			
		||||
ssize_t     fgetxattr(int, const char *, void *, size_t) 231,231,229
 | 
			
		||||
ssize_t     flistxattr(int, char *, size_t) 234,234,232
 | 
			
		||||
int         fremovexattr(int, const char *) 237,237,235
 | 
			
		||||
void *      __mmap2:mmap2(void*, size_t, int, int, int, long)   1
 | 
			
		||||
int         munmap(void *, size_t)  1
 | 
			
		||||
void *      mremap(void *, size_t, size_t, unsigned long)  1
 | 
			
		||||
int         msync(const void *, size_t, int)    1
 | 
			
		||||
int         mprotect(const void *, size_t, int)  1
 | 
			
		||||
int         madvise(const void *, size_t, int)  1
 | 
			
		||||
int         mlock(const void *addr, size_t len)    1
 | 
			
		||||
int         munlock(const void *addr, size_t len)   1
 | 
			
		||||
int         mlockall(int flags)   1
 | 
			
		||||
int         munlockall()   1
 | 
			
		||||
int         mincore(void*  start, size_t  length, unsigned char*  vec)   1
 | 
			
		||||
int         __ioctl:ioctl(int, int, void *)  1
 | 
			
		||||
int         readv(int, const struct iovec *, int)   1
 | 
			
		||||
int         writev(int, const struct iovec *, int)  1
 | 
			
		||||
int         __fcntl:fcntl(int, int, void*)  1
 | 
			
		||||
int         flock(int, int)   1
 | 
			
		||||
int         fchmod(int, mode_t)  1
 | 
			
		||||
int         dup(int)  1
 | 
			
		||||
int         pipe(int *)  1,1,-1
 | 
			
		||||
int         pipe2(int *, int) 1
 | 
			
		||||
int         dup2(int, int)   1
 | 
			
		||||
int         select:_newselect(int, struct fd_set *, struct fd_set *, struct fd_set *, struct timeval *)  1
 | 
			
		||||
int         ftruncate(int, off_t)  1
 | 
			
		||||
int         ftruncate64(int, off64_t) 1
 | 
			
		||||
int         getdents:getdents64(unsigned int, struct dirent *, unsigned int)   1
 | 
			
		||||
int         fsync(int)  1
 | 
			
		||||
int         fdatasync(int) 1
 | 
			
		||||
int         fchown:fchown32(int, uid_t, gid_t)  1,1,-1
 | 
			
		||||
int         fchown:fchown(int, uid_t, gid_t)    -1,-1,1
 | 
			
		||||
void        sync(void)  1
 | 
			
		||||
int         __fcntl64:fcntl64(int, int, void *)  1
 | 
			
		||||
int         __fstatfs64:fstatfs64(int, size_t, struct statfs *)  1
 | 
			
		||||
ssize_t     sendfile(int out_fd, int in_fd, off_t *offset, size_t count)  1
 | 
			
		||||
int         fstatat:fstatat64(int dirfd, const char *path, struct stat *buf, int flags)   1
 | 
			
		||||
int         mkdirat(int dirfd, const char *pathname, mode_t mode)  1
 | 
			
		||||
int         fchownat(int dirfd, const char *path, uid_t owner, gid_t group, int flags)  1
 | 
			
		||||
int         fchmodat(int dirfd, const char *path, mode_t mode, int flags)  1
 | 
			
		||||
int         renameat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath)  1
 | 
			
		||||
int         fsetxattr(int, const char *, const void *, size_t, int) 1
 | 
			
		||||
ssize_t     fgetxattr(int, const char *, void *, size_t) 1
 | 
			
		||||
ssize_t     flistxattr(int, char *, size_t) 1
 | 
			
		||||
int         fremovexattr(int, const char *) 1
 | 
			
		||||
 | 
			
		||||
# file system
 | 
			
		||||
int     link (const char*, const char*)  9
 | 
			
		||||
int     unlink (const char*)             10
 | 
			
		||||
int     unlinkat (int, const char *, int)   328,301,294
 | 
			
		||||
int     chdir (const char*)              12
 | 
			
		||||
int     mknod (const char*, mode_t, dev_t)  14
 | 
			
		||||
int     chmod (const char*,mode_t)          15
 | 
			
		||||
int     chown:chown32(const char *, uid_t, gid_t)  212,212,-1
 | 
			
		||||
int     chown:chown(const char *, uid_t, gid_t)    -1,-1,202
 | 
			
		||||
int     lchown:lchown32 (const char*, uid_t, gid_t)  198,198,-1
 | 
			
		||||
int     lchown:lchown (const char*, uid_t, gid_t)  -1,-1,16
 | 
			
		||||
int     mount (const char*, const char*, const char*, unsigned long, const void*)  21
 | 
			
		||||
int     link (const char*, const char*)  1
 | 
			
		||||
int     unlink (const char*)             1
 | 
			
		||||
int     unlinkat (int, const char *, int)   1
 | 
			
		||||
int     chdir (const char*)              1
 | 
			
		||||
int     mknod (const char*, mode_t, dev_t)  1
 | 
			
		||||
int     chmod (const char*,mode_t)          1
 | 
			
		||||
int     chown:chown32(const char *, uid_t, gid_t)  1,1,-1
 | 
			
		||||
int     chown:chown(const char *, uid_t, gid_t)    -1,-1,1
 | 
			
		||||
int     lchown:lchown32 (const char*, uid_t, gid_t)  1,1,-1
 | 
			
		||||
int     lchown:lchown (const char*, uid_t, gid_t)  -1,-1,1
 | 
			
		||||
int     mount (const char*, const char*, const char*, unsigned long, const void*)  1
 | 
			
		||||
int     umount(const char*)  stub
 | 
			
		||||
int     umount2 (const char*, int)  52
 | 
			
		||||
int     fstat:fstat64(int, struct stat*)    197,197,215
 | 
			
		||||
int     stat:stat64(const char *, struct stat *)  195,195,213
 | 
			
		||||
int     lstat:lstat64(const char *, struct stat *)  196,196,214
 | 
			
		||||
int     mkdir(const char *, mode_t) 39
 | 
			
		||||
int     readlink(const char *, char *, size_t)  85
 | 
			
		||||
int     rmdir(const char *)  40
 | 
			
		||||
int     rename(const char *, const char *)  38
 | 
			
		||||
int     __getcwd:getcwd(char * buf, size_t size)  183,183,203
 | 
			
		||||
int     access(const char *, int)  33
 | 
			
		||||
int     faccessat(int, const char *, int, int)  334,307,300
 | 
			
		||||
int     symlink(const char *, const char *)  83
 | 
			
		||||
int     fchdir(int)    133
 | 
			
		||||
int     truncate(const char*, off_t)    92
 | 
			
		||||
int     setxattr(const char *, const char *, const void *, size_t, int) 226,226,224
 | 
			
		||||
int     lsetxattr(const char *, const char *, const void *, size_t, int) 227,227,225
 | 
			
		||||
ssize_t getxattr(const char *, const char *, void *, size_t) 229,229,227
 | 
			
		||||
ssize_t lgetxattr(const char *, const char *, void *, size_t) 230,230,228
 | 
			
		||||
ssize_t listxattr(const char *, char *, size_t) 232,232,230
 | 
			
		||||
ssize_t llistxattr(const char *, char *, size_t) 233,233,231
 | 
			
		||||
int     removexattr(const char *, const char *) 235,235,233
 | 
			
		||||
int     lremovexattr(const char *, const char *) 236,236,234
 | 
			
		||||
int     __statfs64:statfs64(const char *, size_t, struct statfs *)  266,268,255
 | 
			
		||||
long    unshare(unsigned long)  337,310,303
 | 
			
		||||
int     umount2 (const char*, int)  1
 | 
			
		||||
int     fstat:fstat64(int, struct stat*)    1
 | 
			
		||||
int     stat:stat64(const char *, struct stat *)  1
 | 
			
		||||
int     lstat:lstat64(const char *, struct stat *)  1
 | 
			
		||||
int     mkdir(const char *, mode_t) 1
 | 
			
		||||
int     readlink(const char *, char *, size_t)  1
 | 
			
		||||
int     rmdir(const char *)  1
 | 
			
		||||
int     rename(const char *, const char *)  1
 | 
			
		||||
int     __getcwd:getcwd(char * buf, size_t size)  1
 | 
			
		||||
int     access(const char *, int)  1
 | 
			
		||||
int     faccessat(int, const char *, int, int)  1
 | 
			
		||||
int     symlink(const char *, const char *)  1
 | 
			
		||||
int     fchdir(int)    1
 | 
			
		||||
int     truncate(const char*, off_t)    1
 | 
			
		||||
int     setxattr(const char *, const char *, const void *, size_t, int) 1
 | 
			
		||||
int     lsetxattr(const char *, const char *, const void *, size_t, int) 1
 | 
			
		||||
ssize_t getxattr(const char *, const char *, void *, size_t) 1
 | 
			
		||||
ssize_t lgetxattr(const char *, const char *, void *, size_t) 1
 | 
			
		||||
ssize_t listxattr(const char *, char *, size_t) 1
 | 
			
		||||
ssize_t llistxattr(const char *, char *, size_t) 1
 | 
			
		||||
int     removexattr(const char *, const char *) 1
 | 
			
		||||
int     lremovexattr(const char *, const char *) 1
 | 
			
		||||
int     __statfs64:statfs64(const char *, size_t, struct statfs *)  1
 | 
			
		||||
long    unshare(unsigned long)  1
 | 
			
		||||
 | 
			
		||||
# time
 | 
			
		||||
int           pause ()                       29
 | 
			
		||||
int           gettimeofday(struct timeval*, struct timezone*)       78
 | 
			
		||||
int           settimeofday(const struct timeval*, const struct timezone*)   79
 | 
			
		||||
clock_t       times(struct tms *)       43
 | 
			
		||||
int           nanosleep(const struct timespec *, struct timespec *)   162,162,166
 | 
			
		||||
int           clock_gettime(clockid_t clk_id, struct timespec *tp)    263,265,263
 | 
			
		||||
int           clock_settime(clockid_t clk_id, const struct timespec *tp)  262,264,262
 | 
			
		||||
int           clock_getres(clockid_t clk_id, struct timespec *res)   264,266,264
 | 
			
		||||
int           clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *req, struct timespec *rem)  265,267,265
 | 
			
		||||
int           getitimer(int, const struct itimerval *)   105
 | 
			
		||||
int           setitimer(int, const struct itimerval *, struct itimerval *)  104
 | 
			
		||||
int           __timer_create:timer_create(clockid_t clockid, struct sigevent *evp, timer_t *timerid)    257,259,257
 | 
			
		||||
int           __timer_settime:timer_settime(timer_t, int, const struct itimerspec*, struct itimerspec*) 258,260,258
 | 
			
		||||
int           __timer_gettime:timer_gettime(timer_t, struct itimerspec*)                                259,261,259
 | 
			
		||||
int           __timer_getoverrun:timer_getoverrun(timer_t)                                              260,262,260
 | 
			
		||||
int           __timer_delete:timer_delete(timer_t)                                                      261,263,261
 | 
			
		||||
int           utimes(const char*, const struct timeval tvp[2])                          269,271,267
 | 
			
		||||
int           utimensat(int, const char *, const struct timespec times[2], int)         348,320,316
 | 
			
		||||
int           pause ()                       1
 | 
			
		||||
int           gettimeofday(struct timeval*, struct timezone*)       1
 | 
			
		||||
int           settimeofday(const struct timeval*, const struct timezone*)   1
 | 
			
		||||
clock_t       times(struct tms *)       1
 | 
			
		||||
int           nanosleep(const struct timespec *, struct timespec *)   1
 | 
			
		||||
int           clock_gettime(clockid_t clk_id, struct timespec *tp)    1
 | 
			
		||||
int           clock_settime(clockid_t clk_id, const struct timespec *tp)  1
 | 
			
		||||
int           clock_getres(clockid_t clk_id, struct timespec *res)   1
 | 
			
		||||
int           clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *req, struct timespec *rem)  1
 | 
			
		||||
int           getitimer(int, const struct itimerval *)   1
 | 
			
		||||
int           setitimer(int, const struct itimerval *, struct itimerval *)  1
 | 
			
		||||
int           __timer_create:timer_create(clockid_t clockid, struct sigevent *evp, timer_t *timerid)    1
 | 
			
		||||
int           __timer_settime:timer_settime(timer_t, int, const struct itimerspec*, struct itimerspec*) 1
 | 
			
		||||
int           __timer_gettime:timer_gettime(timer_t, struct itimerspec*)                                1
 | 
			
		||||
int           __timer_getoverrun:timer_getoverrun(timer_t)                                              1
 | 
			
		||||
int           __timer_delete:timer_delete(timer_t)                                                      1
 | 
			
		||||
int           utimes(const char*, const struct timeval tvp[2])                          1
 | 
			
		||||
int           utimensat(int, const char *, const struct timespec times[2], int)         1
 | 
			
		||||
 | 
			
		||||
# signals
 | 
			
		||||
int     sigaction(int, const struct sigaction *, struct sigaction *)  67
 | 
			
		||||
int     sigprocmask(int, const sigset_t *, sigset_t *)  126
 | 
			
		||||
int     __sigsuspend:sigsuspend(int unused1, int unused2, unsigned mask)  72,72,-1
 | 
			
		||||
int     __sigsuspend:sigsuspend(const sigset_t *mask)  -1,-1,72
 | 
			
		||||
int     __rt_sigaction:rt_sigaction (int sig, const struct sigaction *act, struct sigaction *oact, size_t sigsetsize)  174,174,194
 | 
			
		||||
int     __rt_sigprocmask:rt_sigprocmask (int  how, const sigset_t *set, sigset_t *oset, size_t sigsetsize)  175,175,195
 | 
			
		||||
int     __rt_sigtimedwait:rt_sigtimedwait(const sigset_t *set, struct siginfo_t  *info, struct timespec_t  *timeout, size_t  sigset_size)  177,177,197
 | 
			
		||||
int     sigpending(sigset_t *)  73
 | 
			
		||||
int     signalfd4(int fd, const sigset_t *mask, size_t sizemask, int flags)  355,327,324
 | 
			
		||||
int     sigaction(int, const struct sigaction *, struct sigaction *)  1
 | 
			
		||||
int     sigprocmask(int, const sigset_t *, sigset_t *)  1
 | 
			
		||||
int     __sigsuspend:sigsuspend(int unused1, int unused2, unsigned mask)  1,1,-1
 | 
			
		||||
int     __sigsuspend:sigsuspend(const sigset_t *mask)  -1,-1,1
 | 
			
		||||
int     __rt_sigaction:rt_sigaction (int sig, const struct sigaction *act, struct sigaction *oact, size_t sigsetsize)  1
 | 
			
		||||
int     __rt_sigprocmask:rt_sigprocmask (int  how, const sigset_t *set, sigset_t *oset, size_t sigsetsize)  1
 | 
			
		||||
int     __rt_sigtimedwait:rt_sigtimedwait(const sigset_t *set, struct siginfo_t  *info, struct timespec_t  *timeout, size_t  sigset_size)  1
 | 
			
		||||
int     sigpending(sigset_t *)  1
 | 
			
		||||
int     signalfd4(int fd, const sigset_t *mask, size_t sizemask, int flags)  1
 | 
			
		||||
 | 
			
		||||
# sockets
 | 
			
		||||
int           socket(int, int, int)              281,-1,183
 | 
			
		||||
int           socketpair(int, int, int, int*)    288,-1,184
 | 
			
		||||
int           bind(int, struct sockaddr *, int)  282,-1,169
 | 
			
		||||
int           connect(int, struct sockaddr *, socklen_t)   283,-1,170
 | 
			
		||||
int           listen(int, int)                   284,-1,174
 | 
			
		||||
int           accept(int, struct sockaddr *, socklen_t *)  285,-1,168
 | 
			
		||||
int           getsockname(int, struct sockaddr *, socklen_t *)  286,-1,172
 | 
			
		||||
int           getpeername(int, struct sockaddr *, socklen_t *)  287,-1,171
 | 
			
		||||
int           sendto(int, const void *, size_t, int, const struct sockaddr *, socklen_t)  290,-1,180
 | 
			
		||||
int           recvfrom(int, void *, size_t, unsigned int, struct sockaddr *, socklen_t *)  292,-1,176
 | 
			
		||||
int           shutdown(int, int)  293,-1,182
 | 
			
		||||
int           setsockopt(int, int, int, const void *, socklen_t)  294,-1,181
 | 
			
		||||
int           getsockopt(int, int, int, void *, socklen_t *)    295,-1,173
 | 
			
		||||
int           sendmsg(int, const struct msghdr *, unsigned int)  296,-1,179
 | 
			
		||||
int           recvmsg(int, struct msghdr *, unsigned int)   297,-1,177
 | 
			
		||||
int           socket(int, int, int)              1,-1,1
 | 
			
		||||
int           socketpair(int, int, int, int*)    1,-1,1
 | 
			
		||||
int           bind(int, struct sockaddr *, int)  1,-1,1
 | 
			
		||||
int           connect(int, struct sockaddr *, socklen_t)   1,-1,1
 | 
			
		||||
int           listen(int, int)                   1,-1,1
 | 
			
		||||
int           accept(int, struct sockaddr *, socklen_t *)  1,-1,1
 | 
			
		||||
int           getsockname(int, struct sockaddr *, socklen_t *)  1,-1,1
 | 
			
		||||
int           getpeername(int, struct sockaddr *, socklen_t *)  1,-1,1
 | 
			
		||||
int           sendto(int, const void *, size_t, int, const struct sockaddr *, socklen_t)  1,-1,1
 | 
			
		||||
int           recvfrom(int, void *, size_t, unsigned int, struct sockaddr *, socklen_t *)  1,-1,1
 | 
			
		||||
int           shutdown(int, int)  1,-1,1
 | 
			
		||||
int           setsockopt(int, int, int, const void *, socklen_t)  1,-1,1
 | 
			
		||||
int           getsockopt(int, int, int, void *, socklen_t *)    1,-1,1
 | 
			
		||||
int           sendmsg(int, const struct msghdr *, unsigned int)  1,-1,1
 | 
			
		||||
int           recvmsg(int, struct msghdr *, unsigned int)   1,-1,1
 | 
			
		||||
 | 
			
		||||
# sockets for x86. These are done as an "indexed" call to socketcall syscall.
 | 
			
		||||
int           socket:socketcall:1 (int, int, int) -1,102,-1
 | 
			
		||||
int           bind:socketcall:2 (int, struct sockaddr *, int)  -1,102,-1
 | 
			
		||||
int           connect:socketcall:3(int, struct sockaddr *, socklen_t)   -1,102,-1
 | 
			
		||||
int           listen:socketcall:4(int, int)                   -1,102,-1
 | 
			
		||||
int           accept:socketcall:5(int, struct sockaddr *, socklen_t *)  -1,102,-1
 | 
			
		||||
int           getsockname:socketcall:6(int, struct sockaddr *, socklen_t *)  -1,102,-1
 | 
			
		||||
int           getpeername:socketcall:7(int, struct sockaddr *, socklen_t *)  -1,102,-1
 | 
			
		||||
int           socketpair:socketcall:8(int, int, int, int*)    -1,102,-1
 | 
			
		||||
int           sendto:socketcall:11(int, const void *, size_t, int, const struct sockaddr *, socklen_t)  -1,102,-1
 | 
			
		||||
int           recvfrom:socketcall:12(int, void *, size_t, unsigned int, struct sockaddr *, socklen_t *)  -1,102,-1
 | 
			
		||||
int           shutdown:socketcall:13(int, int)  -1,102,-1
 | 
			
		||||
int           setsockopt:socketcall:14(int, int, int, const void *, socklen_t)  -1,102,-1
 | 
			
		||||
int           getsockopt:socketcall:15(int, int, int, void *, socklen_t *)    -1,102,-1
 | 
			
		||||
int           sendmsg:socketcall:16(int, const struct msghdr *, unsigned int)  -1,102,-1
 | 
			
		||||
int           recvmsg:socketcall:17(int, struct msghdr *, unsigned int)   -1,102,-1
 | 
			
		||||
int           socket:socketcall:1 (int, int, int) -1,1,-1
 | 
			
		||||
int           bind:socketcall:2 (int, struct sockaddr *, int)  -1,1,-1
 | 
			
		||||
int           connect:socketcall:3(int, struct sockaddr *, socklen_t)   -1,1,-1
 | 
			
		||||
int           listen:socketcall:4(int, int)                   -1,1,-1
 | 
			
		||||
int           accept:socketcall:5(int, struct sockaddr *, socklen_t *)  -1,1,-1
 | 
			
		||||
int           getsockname:socketcall:6(int, struct sockaddr *, socklen_t *)  -1,1,-1
 | 
			
		||||
int           getpeername:socketcall:7(int, struct sockaddr *, socklen_t *)  -1,1,-1
 | 
			
		||||
int           socketpair:socketcall:8(int, int, int, int*)    -1,1,-1
 | 
			
		||||
int           sendto:socketcall:11(int, const void *, size_t, int, const struct sockaddr *, socklen_t)  -1,1,-1
 | 
			
		||||
int           recvfrom:socketcall:12(int, void *, size_t, unsigned int, struct sockaddr *, socklen_t *)  -1,1,-1
 | 
			
		||||
int           shutdown:socketcall:13(int, int)  -1,1,-1
 | 
			
		||||
int           setsockopt:socketcall:14(int, int, int, const void *, socklen_t)  -1,1,-1
 | 
			
		||||
int           getsockopt:socketcall:15(int, int, int, void *, socklen_t *)    -1,1,-1
 | 
			
		||||
int           sendmsg:socketcall:16(int, const struct msghdr *, unsigned int)  -1,1,-1
 | 
			
		||||
int           recvmsg:socketcall:17(int, struct msghdr *, unsigned int)   -1,1,-1
 | 
			
		||||
 | 
			
		||||
# scheduler & real-time
 | 
			
		||||
int sched_setscheduler(pid_t pid, int policy, const struct sched_param *param)  156,156,160
 | 
			
		||||
int sched_getscheduler(pid_t pid)  157,157,161
 | 
			
		||||
int sched_yield(void)  158,158,162
 | 
			
		||||
int sched_setparam(pid_t pid, const struct sched_param *param)  154,154,158
 | 
			
		||||
int sched_getparam(pid_t pid, struct sched_param *param)  155,155,159
 | 
			
		||||
int sched_get_priority_max(int policy)  159,159,163
 | 
			
		||||
int sched_get_priority_min(int policy)  160,160,164
 | 
			
		||||
int sched_rr_get_interval(pid_t pid, struct timespec *interval)  161,161,165
 | 
			
		||||
int sched_setaffinity(pid_t pid, size_t setsize, const cpu_set_t* set) 241,241,239
 | 
			
		||||
int __sched_getaffinity:sched_getaffinity(pid_t pid, size_t setsize, cpu_set_t* set)  242,242,240
 | 
			
		||||
int __getcpu:getcpu(unsigned *cpu, unsigned *node, void *unused) 345,318,312
 | 
			
		||||
int sched_setscheduler(pid_t pid, int policy, const struct sched_param *param)  1
 | 
			
		||||
int sched_getscheduler(pid_t pid)  1
 | 
			
		||||
int sched_yield(void)  1
 | 
			
		||||
int sched_setparam(pid_t pid, const struct sched_param *param)  1
 | 
			
		||||
int sched_getparam(pid_t pid, struct sched_param *param)  1
 | 
			
		||||
int sched_get_priority_max(int policy)  1
 | 
			
		||||
int sched_get_priority_min(int policy)  1
 | 
			
		||||
int sched_rr_get_interval(pid_t pid, struct timespec *interval)  1
 | 
			
		||||
int sched_setaffinity(pid_t pid, size_t setsize, const cpu_set_t* set) 1
 | 
			
		||||
int __sched_getaffinity:sched_getaffinity(pid_t pid, size_t setsize, cpu_set_t* set)  1
 | 
			
		||||
int __getcpu:getcpu(unsigned *cpu, unsigned *node, void *unused) 1
 | 
			
		||||
 | 
			
		||||
# io priorities
 | 
			
		||||
int ioprio_set(int which, int who, int ioprio) 314,289,314
 | 
			
		||||
int ioprio_get(int which, int who) 315,290,315
 | 
			
		||||
int ioprio_set(int which, int who, int ioprio) 1
 | 
			
		||||
int ioprio_get(int which, int who) 1
 | 
			
		||||
 | 
			
		||||
# other
 | 
			
		||||
int     uname(struct utsname *)  122
 | 
			
		||||
mode_t  umask(mode_t)  60
 | 
			
		||||
int      __reboot:reboot(int, int, int, void *)  88
 | 
			
		||||
int     __syslog:syslog(int, char *, int)  103
 | 
			
		||||
int     init_module(void *, unsigned long, const char *)  128
 | 
			
		||||
int     delete_module(const char*, unsigned int)   129
 | 
			
		||||
int     klogctl:syslog(int, char *, int)   103
 | 
			
		||||
int     sysinfo(struct sysinfo *)  116
 | 
			
		||||
int     personality(unsigned long)  136
 | 
			
		||||
long    perf_event_open(struct perf_event_attr *attr_uptr, pid_t pid, int cpu, int group_fd, unsigned long flags) 364,336,333
 | 
			
		||||
int     uname(struct utsname *)  1
 | 
			
		||||
mode_t  umask(mode_t)  1
 | 
			
		||||
int      __reboot:reboot(int, int, int, void *)  1
 | 
			
		||||
int     __syslog:syslog(int, char *, int)  1
 | 
			
		||||
int     init_module(void *, unsigned long, const char *)  1
 | 
			
		||||
int     delete_module(const char*, unsigned int)   1
 | 
			
		||||
int     klogctl:syslog(int, char *, int)   1
 | 
			
		||||
int     sysinfo(struct sysinfo *)  1
 | 
			
		||||
int     personality(unsigned long)  1
 | 
			
		||||
long    perf_event_open(struct perf_event_attr *attr_uptr, pid_t pid, int cpu, int group_fd, unsigned long flags) 1
 | 
			
		||||
 | 
			
		||||
# futex
 | 
			
		||||
int	futex(void *, int, int, void *, void *, int) 240,240,238
 | 
			
		||||
int	futex(void *, int, int, void *, void *, int) 1
 | 
			
		||||
 | 
			
		||||
# epoll
 | 
			
		||||
int     epoll_create(int size)     250,254,248
 | 
			
		||||
int     epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)    251,255,249
 | 
			
		||||
int     epoll_wait(int epfd, struct epoll_event *events, int max, int timeout)   252,256,250
 | 
			
		||||
int     epoll_create(int size)     1
 | 
			
		||||
int     epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)    1
 | 
			
		||||
int     epoll_wait(int epfd, struct epoll_event *events, int max, int timeout)   1
 | 
			
		||||
 | 
			
		||||
int     inotify_init(void)      316,291,284
 | 
			
		||||
int     inotify_add_watch(int, const char *, unsigned int)  317,292,285
 | 
			
		||||
int     inotify_rm_watch(int, unsigned int)  318,293,286
 | 
			
		||||
int     inotify_init(void)      1
 | 
			
		||||
int     inotify_add_watch(int, const char *, unsigned int)  1
 | 
			
		||||
int     inotify_rm_watch(int, unsigned int)  1
 | 
			
		||||
 | 
			
		||||
int     poll(struct pollfd *, unsigned int, long)  168,168,188
 | 
			
		||||
int     poll(struct pollfd *, unsigned int, long)  1
 | 
			
		||||
 | 
			
		||||
int     eventfd:eventfd2(unsigned int, int)  356,328,325
 | 
			
		||||
int     eventfd:eventfd2(unsigned int, int)  1
 | 
			
		||||
 | 
			
		||||
# ARM-specific ARM_NR_BASE == 0x0f0000 == 983040
 | 
			
		||||
int     __set_tls:__ARM_NR_set_tls(void*)                                 983045,-1,-1
 | 
			
		||||
int     cacheflush:__ARM_NR_cacheflush(long start, long end, long flags)  983042,-1,-1
 | 
			
		||||
int     __set_tls:__ARM_NR_set_tls(void*)                                 1,-1,-1
 | 
			
		||||
int     cacheflush:__ARM_NR_cacheflush(long start, long end, long flags)  1,-1,-1
 | 
			
		||||
 | 
			
		||||
# MIPS-specific
 | 
			
		||||
int	_flush_cache:cacheflush(char *addr, const int nbytes, const int op)	-1,-1,147
 | 
			
		||||
int	syscall(int number,...) -1,-1,0
 | 
			
		||||
int     _flush_cache:cacheflush(char *addr, const int nbytes, const int op) -1,-1,1
 | 
			
		||||
int     syscall(int number,...) -1,-1,1
 | 
			
		||||
 
 | 
			
		||||
@@ -60,52 +60,52 @@ size_t strlen(const char *s)
 | 
			
		||||
    // We need to process 32 bytes per loop to schedule PLD properly
 | 
			
		||||
    // and achieve the maximum bus speed.
 | 
			
		||||
    asm(
 | 
			
		||||
        "ldr     %[v], [ %[s] ], #4         \n"
 | 
			
		||||
        "ldr     %[v], [%[s]], #4           \n"
 | 
			
		||||
        "sub     %[l], %[l], %[s]           \n"
 | 
			
		||||
        "0:                                 \n"
 | 
			
		||||
#if __ARM_HAVE_PLD
 | 
			
		||||
        "pld     [ %[s], #64 ]              \n"
 | 
			
		||||
        "pld     [%[s], #64]                \n"
 | 
			
		||||
#endif
 | 
			
		||||
        "sub     %[t], %[v], %[mask], lsr #7\n"
 | 
			
		||||
        "and     %[t], %[t], %[mask]        \n"
 | 
			
		||||
        "bics    %[t], %[t], %[v]           \n"
 | 
			
		||||
        "ldreq   %[v], [ %[s] ], #4         \n"
 | 
			
		||||
        "ldreq   %[v], [%[s]], #4           \n"
 | 
			
		||||
#if !defined(__OPTIMIZE_SIZE__)
 | 
			
		||||
        "bne     1f                         \n"
 | 
			
		||||
        "sub     %[t], %[v], %[mask], lsr #7\n"
 | 
			
		||||
        "and     %[t], %[t], %[mask]        \n"
 | 
			
		||||
        "bics    %[t], %[t], %[v]           \n"
 | 
			
		||||
        "ldreq   %[v], [ %[s] ], #4         \n"
 | 
			
		||||
        "ldreq   %[v], [%[s]], #4           \n"
 | 
			
		||||
        "bne     1f                         \n"
 | 
			
		||||
        "sub     %[t], %[v], %[mask], lsr #7\n"
 | 
			
		||||
        "and     %[t], %[t], %[mask]        \n"
 | 
			
		||||
        "bics    %[t], %[t], %[v]           \n"
 | 
			
		||||
        "ldreq   %[v], [ %[s] ], #4         \n"
 | 
			
		||||
        "ldreq   %[v], [%[s]], #4           \n"
 | 
			
		||||
        "bne     1f                         \n"
 | 
			
		||||
        "sub     %[t], %[v], %[mask], lsr #7\n"
 | 
			
		||||
        "and     %[t], %[t], %[mask]        \n"
 | 
			
		||||
        "bics    %[t], %[t], %[v]           \n"
 | 
			
		||||
        "ldreq   %[v], [ %[s] ], #4         \n"
 | 
			
		||||
        "ldreq   %[v], [%[s]], #4           \n"
 | 
			
		||||
        "bne     1f                         \n"
 | 
			
		||||
        "sub     %[t], %[v], %[mask], lsr #7\n"
 | 
			
		||||
        "and     %[t], %[t], %[mask]        \n"
 | 
			
		||||
        "bics    %[t], %[t], %[v]           \n"
 | 
			
		||||
        "ldreq   %[v], [ %[s] ], #4         \n"
 | 
			
		||||
        "ldreq   %[v], [%[s]], #4           \n"
 | 
			
		||||
        "bne     1f                         \n"
 | 
			
		||||
        "sub     %[t], %[v], %[mask], lsr #7\n"
 | 
			
		||||
        "and     %[t], %[t], %[mask]        \n"
 | 
			
		||||
        "bics    %[t], %[t], %[v]           \n"
 | 
			
		||||
        "ldreq   %[v], [ %[s] ], #4         \n"
 | 
			
		||||
        "ldreq   %[v], [%[s]], #4           \n"
 | 
			
		||||
        "bne     1f                         \n"
 | 
			
		||||
        "sub     %[t], %[v], %[mask], lsr #7\n"
 | 
			
		||||
        "and     %[t], %[t], %[mask]        \n"
 | 
			
		||||
        "bics    %[t], %[t], %[v]           \n"
 | 
			
		||||
        "ldreq   %[v], [ %[s] ], #4         \n"
 | 
			
		||||
        "ldreq   %[v], [%[s]], #4           \n"
 | 
			
		||||
        "bne     1f                         \n"
 | 
			
		||||
        "sub     %[t], %[v], %[mask], lsr #7\n"
 | 
			
		||||
        "and     %[t], %[t], %[mask]        \n"
 | 
			
		||||
        "bics    %[t], %[t], %[v]           \n"
 | 
			
		||||
        "ldreq   %[v], [ %[s] ], #4         \n"
 | 
			
		||||
        "ldreq   %[v], [%[s]], #4           \n"
 | 
			
		||||
#endif
 | 
			
		||||
        "beq     0b                         \n"
 | 
			
		||||
        "1:                                 \n"
 | 
			
		||||
 
 | 
			
		||||
@@ -24,81 +24,110 @@
 | 
			
		||||
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 | 
			
		||||
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2013 ARM Ltd
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions
 | 
			
		||||
 * are met:
 | 
			
		||||
 * 1. Redistributions of source code must retain the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. The name of the company may not be used to endorse or promote
 | 
			
		||||
 *    products derived from this software without specific prior written
 | 
			
		||||
 *    permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
 | 
			
		||||
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 | 
			
		||||
 * IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
			
		||||
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 | 
			
		||||
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 | 
			
		||||
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
			
		||||
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* Assumes neon instructions and a cache line size of 64 bytes. */
 | 
			
		||||
    /* Prototype: void *memcpy (void *dst, const void *src, size_t count).  */
 | 
			
		||||
 | 
			
		||||
        // This version is tuned for the Cortex-A15 processor.
 | 
			
		||||
 | 
			
		||||
#include <machine/cpu-features.h>
 | 
			
		||||
#include <machine/asm.h>
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * This code assumes it is running on a processor that supports all arm v7
 | 
			
		||||
 * instructions, that supports neon instructions, and that has a 64 byte
 | 
			
		||||
 * cache line.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
        .text
 | 
			
		||||
        .syntax unified
 | 
			
		||||
        .fpu    neon
 | 
			
		||||
 | 
			
		||||
#define CACHE_LINE_SIZE     64
 | 
			
		||||
#define CACHE_LINE_SIZE 64
 | 
			
		||||
 | 
			
		||||
ENTRY(memcpy)
 | 
			
		||||
        .save       {r0, lr}
 | 
			
		||||
        /* start preloading as early as possible */
 | 
			
		||||
        pld         [r1, #(CACHE_LINE_SIZE*0)]
 | 
			
		||||
        stmfd       sp!, {r0, lr}
 | 
			
		||||
        pld         [r1, #(CACHE_LINE_SIZE*1)]
 | 
			
		||||
        // Assumes that n >= 0, and dst, src are valid pointers.
 | 
			
		||||
        // For any sizes less than 832 use the neon code that doesn't
 | 
			
		||||
        // care about the src alignment. This avoids any checks
 | 
			
		||||
        // for src alignment, and offers the best improvement since
 | 
			
		||||
        // smaller sized copies are dominated by the overhead of
 | 
			
		||||
        // the pre and post main loop.
 | 
			
		||||
        // For larger copies, if src and dst cannot both be aligned to
 | 
			
		||||
        // word boundaries, use the neon code.
 | 
			
		||||
        // For all other copies, align dst to a double word boundary
 | 
			
		||||
        // and copy using LDRD/STRD instructions.
 | 
			
		||||
 | 
			
		||||
        /* do we have at least 16-bytes to copy (needed for alignment below) */
 | 
			
		||||
        cmp         r2, #16
 | 
			
		||||
        blo         5f
 | 
			
		||||
        // Save registers (r0 holds the return value):
 | 
			
		||||
        // optimized push {r0, lr}.
 | 
			
		||||
        .save   {r0, lr}
 | 
			
		||||
        pld     [r1, #(CACHE_LINE_SIZE*16)]
 | 
			
		||||
        push    {r0, lr}
 | 
			
		||||
 | 
			
		||||
        /* align destination to cache-line for the write-buffer */
 | 
			
		||||
        cmp     r2, #16
 | 
			
		||||
        blo     copy_less_than_16_unknown_align
 | 
			
		||||
 | 
			
		||||
        cmp     r2, #832
 | 
			
		||||
        bge     check_alignment
 | 
			
		||||
 | 
			
		||||
copy_unknown_alignment:
 | 
			
		||||
        // Unknown alignment of src and dst.
 | 
			
		||||
        // Assumes that the first few bytes have already been prefetched.
 | 
			
		||||
 | 
			
		||||
        // Align destination to 128 bits. The mainloop store instructions
 | 
			
		||||
        // require this alignment or they will throw an exception.
 | 
			
		||||
        rsb         r3, r0, #0
 | 
			
		||||
        ands        r3, r3, #0xF
 | 
			
		||||
        beq         0f
 | 
			
		||||
        beq         2f
 | 
			
		||||
 | 
			
		||||
        /* copy up to 15-bytes (count in r3) */
 | 
			
		||||
        // Copy up to 15 bytes (count in r3).
 | 
			
		||||
        sub         r2, r2, r3
 | 
			
		||||
        movs        ip, r3, lsl #31
 | 
			
		||||
        ldrmib      lr, [r1], #1
 | 
			
		||||
        strmib      lr, [r0], #1
 | 
			
		||||
        ldrcsb      ip, [r1], #1
 | 
			
		||||
        ldrcsb      lr, [r1], #1
 | 
			
		||||
        strcsb      ip, [r0], #1
 | 
			
		||||
        strcsb      lr, [r0], #1
 | 
			
		||||
 | 
			
		||||
        itt         mi
 | 
			
		||||
        ldrbmi      lr, [r1], #1
 | 
			
		||||
        strbmi      lr, [r0], #1
 | 
			
		||||
        itttt       cs
 | 
			
		||||
        ldrbcs      ip, [r1], #1
 | 
			
		||||
        ldrbcs      lr, [r1], #1
 | 
			
		||||
        strbcs      ip, [r0], #1
 | 
			
		||||
        strbcs      lr, [r0], #1
 | 
			
		||||
 | 
			
		||||
        movs        ip, r3, lsl #29
 | 
			
		||||
        bge         1f
 | 
			
		||||
        // copies 4 bytes, destination 32-bits aligned
 | 
			
		||||
        // Copies 4 bytes, dst 32 bits aligned before, at least 64 bits after.
 | 
			
		||||
        vld4.8      {d0[0], d1[0], d2[0], d3[0]}, [r1]!
 | 
			
		||||
        vst4.8      {d0[0], d1[0], d2[0], d3[0]}, [r0, :32]!
 | 
			
		||||
1:      bcc         2f
 | 
			
		||||
        // copies 8 bytes, destination 64-bits aligned
 | 
			
		||||
        // Copies 8 bytes, dst 64 bits aligned before, at least 128 bits after.
 | 
			
		||||
        vld1.8      {d0}, [r1]!
 | 
			
		||||
        vst1.8      {d0}, [r0, :64]!
 | 
			
		||||
2:
 | 
			
		||||
 | 
			
		||||
0:      /* preload immediately the next cache line, which we may need */
 | 
			
		||||
        pld         [r1, #(CACHE_LINE_SIZE*0)]
 | 
			
		||||
        pld         [r1, #(CACHE_LINE_SIZE*1)]
 | 
			
		||||
 | 
			
		||||
        /* make sure we have at least 64 bytes to copy */
 | 
			
		||||
2:      // Make sure we have at least 64 bytes to copy.
 | 
			
		||||
        subs        r2, r2, #64
 | 
			
		||||
        blo         2f
 | 
			
		||||
 | 
			
		||||
        /* Preload all the cache lines we need.
 | 
			
		||||
         * NOTE: The number of pld below depends on CACHE_LINE_SIZE,
 | 
			
		||||
         * ideally we would increase the distance in the main loop to
 | 
			
		||||
         * avoid the goofy code below. In practice this doesn't seem to make
 | 
			
		||||
         * a big difference.
 | 
			
		||||
         * NOTE: The value CACHE_LINE_SIZE * 4 was chosen through
 | 
			
		||||
         * experimentation.
 | 
			
		||||
         */
 | 
			
		||||
        pld         [r1, #(CACHE_LINE_SIZE*2)]
 | 
			
		||||
        pld         [r1, #(CACHE_LINE_SIZE*3)]
 | 
			
		||||
        pld         [r1, #(CACHE_LINE_SIZE*4)]
 | 
			
		||||
 | 
			
		||||
1:      /* The main loop copies 64 bytes at a time */
 | 
			
		||||
1:      // The main loop copies 64 bytes at a time.
 | 
			
		||||
        vld1.8      {d0  - d3},   [r1]!
 | 
			
		||||
        vld1.8      {d4  - d7},   [r1]!
 | 
			
		||||
        pld         [r1, #(CACHE_LINE_SIZE*4)]
 | 
			
		||||
@@ -107,25 +136,24 @@ ENTRY(memcpy)
 | 
			
		||||
        vst1.8      {d4  - d7},   [r0, :128]!
 | 
			
		||||
        bhs         1b
 | 
			
		||||
 | 
			
		||||
2:      /* fix-up the remaining count and make sure we have >= 32 bytes left */
 | 
			
		||||
        add         r2, r2, #64
 | 
			
		||||
        subs        r2, r2, #32
 | 
			
		||||
        blo         4f
 | 
			
		||||
2:      // Fix-up the remaining count and make sure we have >= 32 bytes left.
 | 
			
		||||
        adds        r2, r2, #32
 | 
			
		||||
        blo         3f
 | 
			
		||||
 | 
			
		||||
3:      /* 32 bytes at a time. These cache lines were already preloaded */
 | 
			
		||||
        // 32 bytes. These cache lines were already preloaded.
 | 
			
		||||
        vld1.8      {d0 - d3},  [r1]!
 | 
			
		||||
        subs        r2, r2, #32
 | 
			
		||||
        sub         r2, r2, #32
 | 
			
		||||
        vst1.8      {d0 - d3},  [r0, :128]!
 | 
			
		||||
        bhs         3b
 | 
			
		||||
4:      /* less than 32 left */
 | 
			
		||||
3:      // Less than 32 left.
 | 
			
		||||
        add         r2, r2, #32
 | 
			
		||||
        tst         r2, #0x10
 | 
			
		||||
        beq         5f
 | 
			
		||||
        // copies 16 bytes, 128-bits aligned
 | 
			
		||||
        beq         copy_less_than_16_unknown_align
 | 
			
		||||
        // Copies 16 bytes, destination 128 bits aligned.
 | 
			
		||||
        vld1.8      {d0, d1}, [r1]!
 | 
			
		||||
        vst1.8      {d0, d1}, [r0, :128]!
 | 
			
		||||
 | 
			
		||||
5:      /* copy up to 15-bytes (count in r2) */
 | 
			
		||||
copy_less_than_16_unknown_align:
 | 
			
		||||
        // Copy up to 15 bytes (count in r2).
 | 
			
		||||
        movs        ip, r2, lsl #29
 | 
			
		||||
        bcc         1f
 | 
			
		||||
        vld1.8      {d0}, [r1]!
 | 
			
		||||
@@ -133,14 +161,164 @@ ENTRY(memcpy)
 | 
			
		||||
1:      bge         2f
 | 
			
		||||
        vld4.8      {d0[0], d1[0], d2[0], d3[0]}, [r1]!
 | 
			
		||||
        vst4.8      {d0[0], d1[0], d2[0], d3[0]}, [r0]!
 | 
			
		||||
2:      movs        ip, r2, lsl #31
 | 
			
		||||
        ldrmib      r3, [r1], #1
 | 
			
		||||
        ldrcsb      ip, [r1], #1
 | 
			
		||||
        ldrcsb      lr, [r1], #1
 | 
			
		||||
        strmib      r3, [r0], #1
 | 
			
		||||
        strcsb      ip, [r0], #1
 | 
			
		||||
        strcsb      lr, [r0], #1
 | 
			
		||||
 | 
			
		||||
        ldmfd       sp!, {r0, lr}
 | 
			
		||||
        bx          lr
 | 
			
		||||
2:      // Copy 0 to 4 bytes.
 | 
			
		||||
        lsls        r2, r2, #31
 | 
			
		||||
        itt         ne
 | 
			
		||||
        ldrbne      lr, [r1], #1
 | 
			
		||||
        strbne      lr, [r0], #1
 | 
			
		||||
        itttt       cs
 | 
			
		||||
        ldrbcs      ip, [r1], #1
 | 
			
		||||
        ldrbcs      lr, [r1]
 | 
			
		||||
        strbcs      ip, [r0], #1
 | 
			
		||||
        strbcs      lr, [r0]
 | 
			
		||||
 | 
			
		||||
        pop         {r0, pc}
 | 
			
		||||
 | 
			
		||||
check_alignment:
 | 
			
		||||
        // If src and dst cannot both be aligned to a word boundary,
 | 
			
		||||
        // use the unaligned copy version.
 | 
			
		||||
        eor     r3, r0, r1
 | 
			
		||||
        ands    r3, r3, #0x3
 | 
			
		||||
        bne     copy_unknown_alignment
 | 
			
		||||
 | 
			
		||||
        // To try and improve performance, stack layout changed,
 | 
			
		||||
        // i.e., not keeping the stack looking like users expect
 | 
			
		||||
        // (highest numbered register at highest address).
 | 
			
		||||
        // TODO: Add debug frame directives.
 | 
			
		||||
        // We don't need exception unwind directives, because the code below
 | 
			
		||||
        // does not throw any exceptions and does not call any other functions.
 | 
			
		||||
        // Generally, newlib functions like this lack debug information for
 | 
			
		||||
        // assembler source.
 | 
			
		||||
        .save   {r4, r5}
 | 
			
		||||
        strd    r4, r5, [sp, #-8]!
 | 
			
		||||
        .save   {r6, r7}
 | 
			
		||||
        strd    r6, r7, [sp, #-8]!
 | 
			
		||||
        .save   {r8, r9}
 | 
			
		||||
        strd    r8, r9, [sp, #-8]!
 | 
			
		||||
 | 
			
		||||
        // Optimized for already aligned dst code.
 | 
			
		||||
        ands    ip, r0, #3
 | 
			
		||||
        bne     dst_not_word_aligned
 | 
			
		||||
 | 
			
		||||
word_aligned:
 | 
			
		||||
        // Align the destination buffer to 8 bytes, to make sure double
 | 
			
		||||
        // loads and stores don't cross a cache line boundary,
 | 
			
		||||
        // as they are then more expensive even if the data is in the cache
 | 
			
		||||
        // (require two load/store issue cycles instead of one).
 | 
			
		||||
        // If only one of the buffers is not 8 bytes aligned,
 | 
			
		||||
        // then it's more important to align dst than src,
 | 
			
		||||
        // because there is more penalty for stores
 | 
			
		||||
        // than loads that cross a cacheline boundary.
 | 
			
		||||
        // This check and realignment are only done if there is >= 832
 | 
			
		||||
        // bytes to copy.
 | 
			
		||||
 | 
			
		||||
        // Dst is word aligned, but check if it is already double word aligned.
 | 
			
		||||
        ands    r3, r0, #4
 | 
			
		||||
        beq     1f
 | 
			
		||||
        ldr     r3, [r1], #4
 | 
			
		||||
        str     r3, [r0], #4
 | 
			
		||||
        sub     r2, #4
 | 
			
		||||
 | 
			
		||||
1:      // Can only get here if > 64 bytes to copy, so don't do check r2.
 | 
			
		||||
        sub     r2, #64
 | 
			
		||||
 | 
			
		||||
2:      // Every loop iteration copies 64 bytes.
 | 
			
		||||
        .irp    offset, #0, #8, #16, #24, #32
 | 
			
		||||
        ldrd    r4, r5, [r1, \offset]
 | 
			
		||||
        strd    r4, r5, [r0, \offset]
 | 
			
		||||
        .endr
 | 
			
		||||
 | 
			
		||||
        ldrd    r4, r5, [r1, #40]
 | 
			
		||||
        ldrd    r6, r7, [r1, #48]
 | 
			
		||||
        ldrd    r8, r9, [r1, #56]
 | 
			
		||||
 | 
			
		||||
        // Keep the pld as far from the next load as possible.
 | 
			
		||||
        // The amount to prefetch was determined experimentally using
 | 
			
		||||
        // large sizes, and verifying the prefetch size does not affect
 | 
			
		||||
        // the smaller copies too much.
 | 
			
		||||
        // WARNING: If the ldrd and strd instructions get too far away
 | 
			
		||||
        //          from each other, performance suffers. Three loads
 | 
			
		||||
        //          in a row is the best tradeoff.
 | 
			
		||||
        pld     [r1, #(CACHE_LINE_SIZE*16)]
 | 
			
		||||
        strd    r4, r5, [r0, #40]
 | 
			
		||||
        strd    r6, r7, [r0, #48]
 | 
			
		||||
        strd    r8, r9, [r0, #56]
 | 
			
		||||
 | 
			
		||||
        add     r0, r0, #64
 | 
			
		||||
        add     r1, r1, #64
 | 
			
		||||
        subs    r2, r2, #64
 | 
			
		||||
        bge     2b
 | 
			
		||||
 | 
			
		||||
        // Fix-up the remaining count and make sure we have >= 32 bytes left.
 | 
			
		||||
        adds    r2, r2, #32
 | 
			
		||||
        blo     4f
 | 
			
		||||
 | 
			
		||||
        // Copy 32 bytes. These cache lines were already preloaded.
 | 
			
		||||
        .irp    offset, #0, #8, #16, #24
 | 
			
		||||
        ldrd    r4, r5, [r1, \offset]
 | 
			
		||||
        strd    r4, r5, [r0, \offset]
 | 
			
		||||
        .endr
 | 
			
		||||
        add     r1, r1, #32
 | 
			
		||||
        add     r0, r0, #32
 | 
			
		||||
        sub     r2, r2, #32
 | 
			
		||||
4:      // Less than 32 left.
 | 
			
		||||
        add     r2, r2, #32
 | 
			
		||||
        tst     r2, #0x10
 | 
			
		||||
        beq     5f
 | 
			
		||||
        // Copy 16 bytes.
 | 
			
		||||
        .irp    offset, #0, #8
 | 
			
		||||
        ldrd    r4, r5, [r1, \offset]
 | 
			
		||||
        strd    r4, r5, [r0, \offset]
 | 
			
		||||
        .endr
 | 
			
		||||
        add     r1, r1, #16
 | 
			
		||||
        add     r0, r0, #16
 | 
			
		||||
 | 
			
		||||
5:      // Copy up to 15 bytes (count in r2).
 | 
			
		||||
        movs    ip, r2, lsl #29
 | 
			
		||||
        bcc     1f
 | 
			
		||||
        // Copy 8 bytes.
 | 
			
		||||
        ldrd    r4, r5, [r1], #8
 | 
			
		||||
        strd    r4, r5, [r0], #8
 | 
			
		||||
1:      bge         2f
 | 
			
		||||
        // Copy 4 bytes.
 | 
			
		||||
        ldr     r4, [r1], #4
 | 
			
		||||
        str     r4, [r0], #4
 | 
			
		||||
2:      // Copy 0 to 4 bytes.
 | 
			
		||||
        lsls    r2, r2, #31
 | 
			
		||||
        itt     ne
 | 
			
		||||
        ldrbne  lr, [r1], #1
 | 
			
		||||
        strbne  lr, [r0], #1
 | 
			
		||||
        itttt   cs
 | 
			
		||||
        ldrbcs  ip, [r1], #1
 | 
			
		||||
        ldrbcs  lr, [r1]
 | 
			
		||||
        strbcs  ip, [r0], #1
 | 
			
		||||
        strbcs  lr, [r0]
 | 
			
		||||
 | 
			
		||||
        // Restore registers: optimized pop {r0, pc}
 | 
			
		||||
        ldrd    r8, r9, [sp], #8
 | 
			
		||||
        ldrd    r6, r7, [sp], #8
 | 
			
		||||
        ldrd    r4, r5, [sp], #8
 | 
			
		||||
        pop     {r0, pc}
 | 
			
		||||
 | 
			
		||||
dst_not_word_aligned:
 | 
			
		||||
        // Align dst to word.
 | 
			
		||||
        rsb     ip, ip, #4
 | 
			
		||||
        cmp     ip, #2
 | 
			
		||||
 | 
			
		||||
        itt     gt
 | 
			
		||||
        ldrbgt  lr, [r1], #1
 | 
			
		||||
        strbgt  lr, [r0], #1
 | 
			
		||||
 | 
			
		||||
        itt     ge
 | 
			
		||||
        ldrbge  lr, [r1], #1
 | 
			
		||||
        strbge  lr, [r0], #1
 | 
			
		||||
 | 
			
		||||
        ldrb    lr, [r1], #1
 | 
			
		||||
        strb    lr, [r0], #1
 | 
			
		||||
 | 
			
		||||
        sub     r2, r2, ip
 | 
			
		||||
 | 
			
		||||
        // Src is guaranteed to be at least word aligned by this point.
 | 
			
		||||
        b       word_aligned
 | 
			
		||||
END(memcpy)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2008 The Android Open Source Project
 | 
			
		||||
 * Copyright (C) 2013 The Android Open Source Project
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
@@ -35,11 +35,12 @@
 | 
			
		||||
         * memset() returns its first argument.
 | 
			
		||||
		 */
 | 
			
		||||
 | 
			
		||||
    .fpu    neon
 | 
			
		||||
        .fpu        neon
 | 
			
		||||
        .syntax     unified
 | 
			
		||||
 | 
			
		||||
ENTRY(bzero)
 | 
			
		||||
        mov     r2, r1
 | 
			
		||||
        mov     r1, #0
 | 
			
		||||
        mov         r2, r1
 | 
			
		||||
        mov         r1, #0
 | 
			
		||||
        // Fall through to memset...
 | 
			
		||||
END(bzero)
 | 
			
		||||
 | 
			
		||||
@@ -47,60 +48,117 @@ ENTRY(memset)
 | 
			
		||||
        .save       {r0}
 | 
			
		||||
        stmfd       sp!, {r0}
 | 
			
		||||
 | 
			
		||||
        vdup.8      q0, r1
 | 
			
		||||
 | 
			
		||||
        /* do we have at least 16-bytes to write (needed for alignment below) */
 | 
			
		||||
        // The new algorithm is slower for copies < 16 so use the old
 | 
			
		||||
        // neon code in that case.
 | 
			
		||||
        cmp         r2, #16
 | 
			
		||||
        blo         3f
 | 
			
		||||
        blo         set_less_than_16_unknown_align
 | 
			
		||||
 | 
			
		||||
        /* align destination to 16 bytes for the write-buffer */
 | 
			
		||||
        rsb         r3, r0, #0
 | 
			
		||||
        ands        r3, r3, #0xF
 | 
			
		||||
        beq         2f
 | 
			
		||||
        // Use strd which requires an even and odd register so move the
 | 
			
		||||
        // values so that:
 | 
			
		||||
        //   r0 and r1 contain the memset value
 | 
			
		||||
        //   r2 is the number of bytes to set
 | 
			
		||||
        //   r3 is the destination pointer
 | 
			
		||||
        mov         r3, r0
 | 
			
		||||
 | 
			
		||||
        /* write up to 15-bytes (count in r3) */
 | 
			
		||||
        sub         r2, r2, r3
 | 
			
		||||
        movs        ip, r3, lsl #31
 | 
			
		||||
        strmib      r1, [r0], #1
 | 
			
		||||
        strcsb      r1, [r0], #1
 | 
			
		||||
        strcsb      r1, [r0], #1
 | 
			
		||||
        movs        ip, r3, lsl #29
 | 
			
		||||
        bge         1f
 | 
			
		||||
        // Copy the byte value in every byte of r1.
 | 
			
		||||
        mov         r1, r1, lsl #24
 | 
			
		||||
        orr         r1, r1, r1, lsr #8
 | 
			
		||||
        orr         r1, r1, r1, lsr #16
 | 
			
		||||
 | 
			
		||||
        // writes 4 bytes, 32-bits aligned
 | 
			
		||||
        vst1.32     {d0[0]}, [r0, :32]!
 | 
			
		||||
1:      bcc         2f
 | 
			
		||||
check_alignment:
 | 
			
		||||
        // Align destination to a double word to avoid the strd crossing
 | 
			
		||||
        // a cache line boundary.
 | 
			
		||||
        ands        ip, r3, #7
 | 
			
		||||
        bne         do_double_word_align
 | 
			
		||||
 | 
			
		||||
        // writes 8 bytes, 64-bits aligned
 | 
			
		||||
        vst1.8      {d0}, [r0, :64]!
 | 
			
		||||
2:
 | 
			
		||||
        /* make sure we have at least 32 bytes to write */
 | 
			
		||||
        subs        r2, r2, #32
 | 
			
		||||
        blo         2f
 | 
			
		||||
        vmov        q1, q0
 | 
			
		||||
double_word_aligned:
 | 
			
		||||
        mov         r0, r1
 | 
			
		||||
 | 
			
		||||
1:      /* The main loop writes 32 bytes at a time */
 | 
			
		||||
        subs        r2, r2, #32
 | 
			
		||||
        vst1.8      {d0 - d3}, [r0, :128]!
 | 
			
		||||
        bhs         1b
 | 
			
		||||
        subs        r2, #64
 | 
			
		||||
        blo         set_less_than_64
 | 
			
		||||
 | 
			
		||||
2:      /* less than 32 left */
 | 
			
		||||
        add         r2, r2, #32
 | 
			
		||||
        tst         r2, #0x10
 | 
			
		||||
        beq         3f
 | 
			
		||||
1:      // Main loop sets 64 bytes at a time.
 | 
			
		||||
        .irp        offset, #0, #8, #16, #24, #32, #40, #48, #56
 | 
			
		||||
        strd        r0, r1, [r3, \offset]
 | 
			
		||||
        .endr
 | 
			
		||||
 | 
			
		||||
        // writes 16 bytes, 128-bits aligned
 | 
			
		||||
        vst1.8      {d0, d1}, [r0, :128]!
 | 
			
		||||
3:      /* write up to 15-bytes (count in r2) */
 | 
			
		||||
        add         r3, #64
 | 
			
		||||
        subs        r2, #64
 | 
			
		||||
        bge         1b
 | 
			
		||||
 | 
			
		||||
set_less_than_64:
 | 
			
		||||
        // Restore r2 to the count of bytes left to set.
 | 
			
		||||
        add         r2, #64
 | 
			
		||||
        lsls        ip, r2, #27
 | 
			
		||||
        bcc         set_less_than_32
 | 
			
		||||
        // Set 32 bytes.
 | 
			
		||||
        .irp        offset, #0, #8, #16, #24
 | 
			
		||||
        strd        r0, r1, [r3, \offset]
 | 
			
		||||
        .endr
 | 
			
		||||
        add         r3, #32
 | 
			
		||||
 | 
			
		||||
set_less_than_32:
 | 
			
		||||
        bpl         set_less_than_16
 | 
			
		||||
        // Set 16 bytes.
 | 
			
		||||
        .irp        offset, #0, #8
 | 
			
		||||
        strd        r0, r1, [r3, \offset]
 | 
			
		||||
        .endr
 | 
			
		||||
        add         r3, #16
 | 
			
		||||
 | 
			
		||||
set_less_than_16:
 | 
			
		||||
        // Less than 16 bytes to set.
 | 
			
		||||
        lsls        ip, r2, #29
 | 
			
		||||
        bcc         set_less_than_8
 | 
			
		||||
 | 
			
		||||
        // Set 8 bytes.
 | 
			
		||||
        strd        r0, r1, [r3], #8
 | 
			
		||||
 | 
			
		||||
set_less_than_8:
 | 
			
		||||
        bpl         set_less_than_4
 | 
			
		||||
        // Set 4 bytes
 | 
			
		||||
        str         r1, [r3], #4
 | 
			
		||||
 | 
			
		||||
set_less_than_4:
 | 
			
		||||
        lsls        ip, r2, #31
 | 
			
		||||
        it          ne
 | 
			
		||||
        strbne      r1, [r3], #1
 | 
			
		||||
        itt         cs
 | 
			
		||||
        strbcs      r1, [r3], #1
 | 
			
		||||
        strbcs      r1, [r3]
 | 
			
		||||
 | 
			
		||||
        ldmfd       sp!, {r0}
 | 
			
		||||
        bx          lr
 | 
			
		||||
 | 
			
		||||
do_double_word_align:
 | 
			
		||||
        rsb         ip, ip, #8
 | 
			
		||||
        sub         r2, r2, ip
 | 
			
		||||
        movs        r0, ip, lsl #31
 | 
			
		||||
        it          mi
 | 
			
		||||
        strbmi      r1, [r3], #1
 | 
			
		||||
        itt         cs
 | 
			
		||||
        strbcs      r1, [r3], #1
 | 
			
		||||
        strbcs      r1, [r3], #1
 | 
			
		||||
 | 
			
		||||
        // Dst is at least word aligned by this point.
 | 
			
		||||
        cmp         ip, #4
 | 
			
		||||
        blo         double_word_aligned
 | 
			
		||||
        str         r1, [r3], #4
 | 
			
		||||
        b           double_word_aligned
 | 
			
		||||
 | 
			
		||||
set_less_than_16_unknown_align:
 | 
			
		||||
        // Set up to 15 bytes.
 | 
			
		||||
        vdup.8      d0, r1
 | 
			
		||||
        movs        ip, r2, lsl #29
 | 
			
		||||
        bcc         1f
 | 
			
		||||
        vst1.8      {d0}, [r0]!
 | 
			
		||||
1:      bge         2f
 | 
			
		||||
        vst1.32     {d0[0]}, [r0]!
 | 
			
		||||
2:      movs        ip, r2, lsl #31
 | 
			
		||||
        strmib      r1, [r0], #1
 | 
			
		||||
        strcsb      r1, [r0], #1
 | 
			
		||||
        strcsb      r1, [r0], #1
 | 
			
		||||
        it          mi
 | 
			
		||||
        strbmi      r1, [r0], #1
 | 
			
		||||
        itt         cs
 | 
			
		||||
        strbcs      r1, [r0], #1
 | 
			
		||||
        strbcs      r1, [r0], #1
 | 
			
		||||
        ldmfd       sp!, {r0}
 | 
			
		||||
        bx          lr
 | 
			
		||||
END(memset)
 | 
			
		||||
 
 | 
			
		||||
@@ -45,7 +45,7 @@
 | 
			
		||||
extern "C" void *__memcpy_chk(void *dest, const void *src,
 | 
			
		||||
              size_t copy_amount, size_t dest_len)
 | 
			
		||||
{
 | 
			
		||||
    if (__builtin_expect(copy_amount > dest_len, 0)) {
 | 
			
		||||
    if (__predict_false(copy_amount > dest_len)) {
 | 
			
		||||
        __fortify_chk_fail("memcpy buffer overflow",
 | 
			
		||||
                             BIONIC_EVENT_MEMCPY_BUFFER_OVERFLOW);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -44,7 +44,7 @@
 | 
			
		||||
extern "C" void *__memmove_chk (void *dest, const void *src,
 | 
			
		||||
              size_t len, size_t dest_len)
 | 
			
		||||
{
 | 
			
		||||
    if (len > dest_len) {
 | 
			
		||||
    if (__predict_false(len > dest_len)) {
 | 
			
		||||
        __fortify_chk_fail("memmove buffer overflow",
 | 
			
		||||
                             BIONIC_EVENT_MEMMOVE_BUFFER_OVERFLOW);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -42,7 +42,7 @@
 | 
			
		||||
 * greater than 0.
 | 
			
		||||
 */
 | 
			
		||||
extern "C" void *__memset_chk (void *dest, int c, size_t n, size_t dest_len) {
 | 
			
		||||
    if (n > dest_len) {
 | 
			
		||||
    if (__predict_false(n > dest_len)) {
 | 
			
		||||
        __fortify_chk_fail("memset buffer overflow",
 | 
			
		||||
                             BIONIC_EVENT_MEMSET_BUFFER_OVERFLOW);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -32,6 +32,5 @@
 | 
			
		||||
#include "libc_logging.h"
 | 
			
		||||
 | 
			
		||||
void __stack_chk_fail() {
 | 
			
		||||
  __libc_format_log(ANDROID_LOG_FATAL, "libc", "stack corruption detected");
 | 
			
		||||
  abort();
 | 
			
		||||
  __libc_fatal("stack corruption detected");
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -44,7 +44,7 @@
 | 
			
		||||
extern "C" char *__strcpy_chk (char *dest, const char *src, size_t dest_len) {
 | 
			
		||||
    // TODO: optimize so we don't scan src twice.
 | 
			
		||||
    size_t src_len = strlen(src) + 1;
 | 
			
		||||
    if (src_len > dest_len) {
 | 
			
		||||
    if (__predict_false(src_len > dest_len)) {
 | 
			
		||||
        __fortify_chk_fail("strcpy buffer overflow",
 | 
			
		||||
                             BIONIC_EVENT_STRCPY_BUFFER_OVERFLOW);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -45,7 +45,7 @@
 | 
			
		||||
extern "C" size_t __strlcat_chk(char *dest, const char *src,
 | 
			
		||||
              size_t supplied_size, size_t dest_len_from_compiler)
 | 
			
		||||
{
 | 
			
		||||
    if (supplied_size > dest_len_from_compiler) {
 | 
			
		||||
    if (__predict_false(supplied_size > dest_len_from_compiler)) {
 | 
			
		||||
        __fortify_chk_fail("strlcat buffer overflow", 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -45,7 +45,7 @@
 | 
			
		||||
extern "C" size_t __strlcpy_chk(char *dest, const char *src,
 | 
			
		||||
              size_t supplied_size, size_t dest_len_from_compiler)
 | 
			
		||||
{
 | 
			
		||||
    if (supplied_size > dest_len_from_compiler) {
 | 
			
		||||
    if (__predict_false(supplied_size > dest_len_from_compiler)) {
 | 
			
		||||
        __fortify_chk_fail("strlcpy buffer overflow", 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -56,7 +56,7 @@
 | 
			
		||||
extern "C" size_t __strlen_chk(const char *s, size_t s_len) {
 | 
			
		||||
    size_t ret = strlen(s);
 | 
			
		||||
 | 
			
		||||
    if (__builtin_expect(ret >= s_len, 0)) {
 | 
			
		||||
    if (__predict_false(ret >= s_len)) {
 | 
			
		||||
        __fortify_chk_fail("strlen read overflow", 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -44,7 +44,7 @@
 | 
			
		||||
extern "C" char *__strncpy_chk (char *dest, const char *src,
 | 
			
		||||
              size_t len, size_t dest_len)
 | 
			
		||||
{
 | 
			
		||||
    if (len > dest_len) {
 | 
			
		||||
    if (__predict_false(len > dest_len)) {
 | 
			
		||||
        __fortify_chk_fail("strncpy buffer overflow",
 | 
			
		||||
                             BIONIC_EVENT_STRNCPY_BUFFER_OVERFLOW);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -42,7 +42,7 @@
 | 
			
		||||
 * greater than 0.
 | 
			
		||||
 */
 | 
			
		||||
extern "C" mode_t __umask_chk(mode_t mode) {
 | 
			
		||||
    if ((mode & 0777) != mode) {
 | 
			
		||||
    if (__predict_false((mode & 0777) != mode)) {
 | 
			
		||||
        __fortify_chk_fail("umask called with invalid mask", 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -50,7 +50,7 @@ extern "C" int __vsnprintf_chk(
 | 
			
		||||
        const char *format,
 | 
			
		||||
        va_list va)
 | 
			
		||||
{
 | 
			
		||||
    if (supplied_size > dest_len_from_compiler) {
 | 
			
		||||
    if (__predict_false(supplied_size > dest_len_from_compiler)) {
 | 
			
		||||
        __fortify_chk_fail("vsnprintf buffer overflow", 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -28,27 +28,16 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#include "libc_logging.h"
 | 
			
		||||
 | 
			
		||||
// We log to stderr for the benefit of "adb shell" users, and the log for the benefit
 | 
			
		||||
// of regular app developers who want to see their asserts.
 | 
			
		||||
 | 
			
		||||
void __assert(const char* file, int line, const char* failed_expression) {
 | 
			
		||||
  const char* fmt = "%s:%d: assertion \"%s\" failed\n";
 | 
			
		||||
  __libc_format_log(ANDROID_LOG_FATAL, "libc", fmt, file, line, failed_expression);
 | 
			
		||||
  fprintf(stderr, fmt, file, line, failed_expression);
 | 
			
		||||
  abort();
 | 
			
		||||
  __libc_fatal("%s:%d: assertion \"%s\" failed", file, line, failed_expression);
 | 
			
		||||
  /* NOTREACHED */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void __assert2(const char* file, int line, const char* function, const char* failed_expression) {
 | 
			
		||||
  const char* fmt = "%s:%d: %s: assertion \"%s\" failed\n";
 | 
			
		||||
  __libc_format_log(ANDROID_LOG_FATAL, "libc", fmt, file, line, function, failed_expression);
 | 
			
		||||
  fprintf(stderr, fmt, file, line, function, failed_expression);
 | 
			
		||||
  abort();
 | 
			
		||||
  __libc_fatal("%s:%d: %s: assertion \"%s\" failed", file, line, function, failed_expression);
 | 
			
		||||
  /* NOTREACHED */
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -91,6 +91,24 @@ static _Unwind_Reason_Code trace_function(__unwind_context* context, void* arg)
 | 
			
		||||
    return _URC_NO_REASON;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#ifdef __arm__
 | 
			
		||||
  /*
 | 
			
		||||
   * The instruction pointer is pointing at the instruction after the bl(x), and
 | 
			
		||||
   * the _Unwind_Backtrace routine already masks the Thumb mode indicator (LSB
 | 
			
		||||
   * in PC). So we need to do a quick check here to find out if the previous
 | 
			
		||||
   * instruction is a Thumb-mode BLX(2). If so subtract 2 otherwise 4 from PC.
 | 
			
		||||
   */
 | 
			
		||||
  if (ip != 0) {
 | 
			
		||||
    short* ptr = reinterpret_cast<short*>(ip);
 | 
			
		||||
    // Thumb BLX(2)
 | 
			
		||||
    if ((*(ptr-1) & 0xff80) == 0x4780) {
 | 
			
		||||
      ip -= 2;
 | 
			
		||||
    } else {
 | 
			
		||||
      ip -= 4;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  state->frames[state->frame_count++] = ip;
 | 
			
		||||
  return (state->frame_count >= state->max_depth) ? _URC_END_OF_STACK : _URC_NO_REASON;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -16,15 +16,7 @@
 | 
			
		||||
 | 
			
		||||
#include "dlmalloc.h"
 | 
			
		||||
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <sys/mman.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
 | 
			
		||||
#include <linux/ashmem.h>
 | 
			
		||||
 | 
			
		||||
#include <private/libc_logging.h>
 | 
			
		||||
#include "private/libc_logging.h"
 | 
			
		||||
 | 
			
		||||
// Send dlmalloc errors to the log.
 | 
			
		||||
static void __bionic_heap_corruption_error(const char* function);
 | 
			
		||||
@@ -33,51 +25,16 @@ static void __bionic_heap_usage_error(const char* function, void* address);
 | 
			
		||||
#define CORRUPTION_ERROR_ACTION(m) __bionic_heap_corruption_error(__FUNCTION__)
 | 
			
		||||
#define USAGE_ERROR_ACTION(m,p) __bionic_heap_usage_error(__FUNCTION__, p)
 | 
			
		||||
 | 
			
		||||
// We use ashmem to name the anonymous private regions created by dlmalloc.
 | 
			
		||||
static void* __bionic_named_anonymous_mmap(size_t length);
 | 
			
		||||
#define MMAP(s) __bionic_named_anonymous_mmap(s)
 | 
			
		||||
 | 
			
		||||
// Ugly inclusion of C file so that bionic specific #defines configure dlmalloc.
 | 
			
		||||
#include "../upstream-dlmalloc/malloc.c"
 | 
			
		||||
 | 
			
		||||
static void __bionic_heap_corruption_error(const char* function) {
 | 
			
		||||
  __libc_format_log(ANDROID_LOG_FATAL, "libc", "@@@ ABORTING: heap corruption detected by %s",
 | 
			
		||||
                    function);
 | 
			
		||||
  abort();
 | 
			
		||||
  __libc_fatal("@@@ ABORTING: heap corruption detected by %s", function);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void __bionic_heap_usage_error(const char* function, void* address) {
 | 
			
		||||
  __libc_format_log(ANDROID_LOG_FATAL, "libc",
 | 
			
		||||
                    "@@@ ABORTING: invalid address or address of corrupt block %p passed to %s",
 | 
			
		||||
                    address, function);
 | 
			
		||||
  __libc_fatal("@@@ ABORTING: invalid address or address of corrupt block %p passed to %s",
 | 
			
		||||
               address, function);
 | 
			
		||||
  // So that we can get a memory dump around the specific address.
 | 
			
		||||
  *((int**) 0xdeadbaad) = (int*) address;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int __ashmem_create_region(const char* name, size_t size) {
 | 
			
		||||
  int fd = open("/dev/ashmem", O_RDWR);
 | 
			
		||||
  if (fd == -1) {
 | 
			
		||||
    return fd;
 | 
			
		||||
  }
 | 
			
		||||
  int rc = ioctl(fd, ASHMEM_SET_NAME, name);
 | 
			
		||||
  if (rc < 0) {
 | 
			
		||||
    close(fd);
 | 
			
		||||
    return rc;
 | 
			
		||||
  }
 | 
			
		||||
  rc = ioctl(fd, ASHMEM_SET_SIZE, size);
 | 
			
		||||
  if (rc < 0) {
 | 
			
		||||
    close(fd);
 | 
			
		||||
    return rc;
 | 
			
		||||
  }
 | 
			
		||||
  return fd;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void* __bionic_named_anonymous_mmap(size_t length) {
 | 
			
		||||
  int fd = __ashmem_create_region("libc malloc", length);
 | 
			
		||||
  if (fd < 0) {
 | 
			
		||||
    return MAP_FAILED;
 | 
			
		||||
  }
 | 
			
		||||
  void* result = mmap(NULL, length, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
 | 
			
		||||
  close (fd);
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -25,17 +25,10 @@
 | 
			
		||||
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
#define _GNU_SOURCE 1
 | 
			
		||||
#include <sched.h>
 | 
			
		||||
 | 
			
		||||
int  sched_getaffinity(pid_t pid, size_t setsize, cpu_set_t* set)
 | 
			
		||||
{
 | 
			
		||||
    int ret = __sched_getaffinity(pid, setsize, set);
 | 
			
		||||
    if (ret >= 0) {
 | 
			
		||||
        if ((size_t)ret < setsize) {
 | 
			
		||||
            memset((char*)set + ret, '\0', setsize - (size_t)ret);
 | 
			
		||||
        }
 | 
			
		||||
        ret = 0;
 | 
			
		||||
    }
 | 
			
		||||
    return ret;
 | 
			
		||||
#include <sys/eventfd.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
int eventfd_read(int fd, eventfd_t* value) {
 | 
			
		||||
  return (read(fd, value, sizeof(*value)) == sizeof(*value)) ? 0 : -1;
 | 
			
		||||
}
 | 
			
		||||
@@ -29,25 +29,6 @@
 | 
			
		||||
#include <sys/eventfd.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
/* We duplicate the GLibc error semantics, which are poorly defined
 | 
			
		||||
 * if the read() or write() does not return the proper number of bytes.
 | 
			
		||||
 */
 | 
			
		||||
int eventfd_read(int fd, eventfd_t *counter)
 | 
			
		||||
{
 | 
			
		||||
    int ret = read(fd, counter, sizeof(*counter));
 | 
			
		||||
 | 
			
		||||
    if (ret == sizeof(*counter))
 | 
			
		||||
        return 0;
 | 
			
		||||
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int eventfd_write(int fd, eventfd_t counter)
 | 
			
		||||
{
 | 
			
		||||
    int ret = write(fd, &counter, sizeof(counter));
 | 
			
		||||
 | 
			
		||||
    if (ret == sizeof(counter))
 | 
			
		||||
        return 0;
 | 
			
		||||
 | 
			
		||||
    return -1;
 | 
			
		||||
int eventfd_write(int fd, eventfd_t value) {
 | 
			
		||||
  return (write(fd, &value, sizeof(value)) == sizeof(value)) ? 0 : -1;
 | 
			
		||||
}
 | 
			
		||||
@@ -45,6 +45,7 @@
 | 
			
		||||
#include "private/KernelArgumentBlock.h"
 | 
			
		||||
#include "pthread_internal.h"
 | 
			
		||||
 | 
			
		||||
extern "C" abort_msg_t** __abort_message_ptr;
 | 
			
		||||
extern "C" unsigned __get_sp(void);
 | 
			
		||||
extern "C" int __system_properties_init(void);
 | 
			
		||||
 | 
			
		||||
@@ -96,6 +97,7 @@ void __libc_init_common(KernelArgumentBlock& args) {
 | 
			
		||||
  errno = 0;
 | 
			
		||||
  __libc_auxv = args.auxv;
 | 
			
		||||
  __progname = args.argv[0] ? args.argv[0] : "<unknown>";
 | 
			
		||||
  __abort_message_ptr = args.abort_message_ptr;
 | 
			
		||||
 | 
			
		||||
  // AT_RANDOM is a pointer to 16 bytes of randomness on the stack.
 | 
			
		||||
  __stack_chk_guard = *reinterpret_cast<uintptr_t*>(getauxval(AT_RANDOM));
 | 
			
		||||
 
 | 
			
		||||
@@ -31,228 +31,96 @@
 | 
			
		||||
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
/*** Generic output sink
 | 
			
		||||
 ***/
 | 
			
		||||
 | 
			
		||||
struct Out {
 | 
			
		||||
  void *opaque;
 | 
			
		||||
  void (*send)(void *opaque, const char *data, int len);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void out_send(Out *o, const char *data, size_t len) {
 | 
			
		||||
    o->send(o->opaque, data, (int)len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
out_send_repeat(Out *o, char ch, int count)
 | 
			
		||||
{
 | 
			
		||||
    char pad[8];
 | 
			
		||||
    const int padSize = (int)sizeof(pad);
 | 
			
		||||
 | 
			
		||||
    memset(pad, ch, sizeof(pad));
 | 
			
		||||
    while (count > 0) {
 | 
			
		||||
        int avail = count;
 | 
			
		||||
        if (avail > padSize) {
 | 
			
		||||
            avail = padSize;
 | 
			
		||||
        }
 | 
			
		||||
        o->send(o->opaque, pad, avail);
 | 
			
		||||
        count -= avail;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* forward declaration */
 | 
			
		||||
static void out_vformat(Out* o, const char* format, va_list args);
 | 
			
		||||
 | 
			
		||||
/*** Bounded buffer output
 | 
			
		||||
 ***/
 | 
			
		||||
 | 
			
		||||
struct BufOut {
 | 
			
		||||
  Out out[1];
 | 
			
		||||
  char *buffer;
 | 
			
		||||
  char *pos;
 | 
			
		||||
  char *end;
 | 
			
		||||
  int total;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void buf_out_send(void *opaque, const char *data, int len) {
 | 
			
		||||
    BufOut *bo = reinterpret_cast<BufOut*>(opaque);
 | 
			
		||||
 | 
			
		||||
    if (len < 0) {
 | 
			
		||||
        len = strlen(data);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bo->total += len;
 | 
			
		||||
 | 
			
		||||
    while (len > 0) {
 | 
			
		||||
        int avail = bo->end - bo->pos;
 | 
			
		||||
        if (avail == 0)
 | 
			
		||||
            break;
 | 
			
		||||
        if (avail > len)
 | 
			
		||||
            avail = len;
 | 
			
		||||
        memcpy(bo->pos, data, avail);
 | 
			
		||||
        bo->pos += avail;
 | 
			
		||||
        bo->pos[0] = '\0';
 | 
			
		||||
        len -= avail;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Out*
 | 
			
		||||
buf_out_init(BufOut *bo, char *buffer, size_t size)
 | 
			
		||||
{
 | 
			
		||||
    if (size == 0)
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
    bo->out->opaque = bo;
 | 
			
		||||
    bo->out->send   = buf_out_send;
 | 
			
		||||
    bo->buffer      = buffer;
 | 
			
		||||
    bo->end         = buffer + size - 1;
 | 
			
		||||
    bo->pos         = bo->buffer;
 | 
			
		||||
    bo->pos[0]      = '\0';
 | 
			
		||||
    bo->total       = 0;
 | 
			
		||||
 | 
			
		||||
    return bo->out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
buf_out_length(BufOut *bo)
 | 
			
		||||
{
 | 
			
		||||
    return bo->total;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
vformat_buffer(char *buff, size_t buf_size, const char *format, va_list args)
 | 
			
		||||
{
 | 
			
		||||
    BufOut bo;
 | 
			
		||||
    Out *out;
 | 
			
		||||
 | 
			
		||||
    out = buf_out_init(&bo, buff, buf_size);
 | 
			
		||||
    if (out == NULL)
 | 
			
		||||
        return 0;
 | 
			
		||||
 | 
			
		||||
    out_vformat(out, format, args);
 | 
			
		||||
 | 
			
		||||
    return buf_out_length(&bo);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int __libc_format_buffer(char* buffer, size_t buffer_size, const char* format, ...) {
 | 
			
		||||
  va_list args;
 | 
			
		||||
  va_start(args, format);
 | 
			
		||||
  int result = vformat_buffer(buffer, buffer_size, format, args);
 | 
			
		||||
  va_end(args);
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*** File descriptor output
 | 
			
		||||
 ***/
 | 
			
		||||
 | 
			
		||||
struct FdOut {
 | 
			
		||||
  Out out[1];
 | 
			
		||||
  int fd;
 | 
			
		||||
  int total;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
fd_out_send(void *opaque, const char *data, int len)
 | 
			
		||||
{
 | 
			
		||||
    FdOut *fdo = reinterpret_cast<FdOut*>(opaque);
 | 
			
		||||
 | 
			
		||||
    if (len < 0)
 | 
			
		||||
        len = strlen(data);
 | 
			
		||||
 | 
			
		||||
    while (len > 0) {
 | 
			
		||||
        int ret = write(fdo->fd, data, len);
 | 
			
		||||
        if (ret < 0) {
 | 
			
		||||
            if (errno == EINTR)
 | 
			
		||||
                continue;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        data += ret;
 | 
			
		||||
        len -= ret;
 | 
			
		||||
        fdo->total += ret;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Out*
 | 
			
		||||
fd_out_init(FdOut *fdo, int  fd)
 | 
			
		||||
{
 | 
			
		||||
    fdo->out->opaque = fdo;
 | 
			
		||||
    fdo->out->send = fd_out_send;
 | 
			
		||||
    fdo->fd = fd;
 | 
			
		||||
    fdo->total = 0;
 | 
			
		||||
 | 
			
		||||
    return fdo->out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
fd_out_length(FdOut *fdo)
 | 
			
		||||
{
 | 
			
		||||
    return fdo->total;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int __libc_format_fd(int fd, const char* format, ...) {
 | 
			
		||||
  FdOut fdo;
 | 
			
		||||
  Out* out = fd_out_init(&fdo, fd);
 | 
			
		||||
  if (out == NULL) {
 | 
			
		||||
    return 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  va_list args;
 | 
			
		||||
  va_start(args, format);
 | 
			
		||||
  out_vformat(out, format, args);
 | 
			
		||||
  va_end(args);
 | 
			
		||||
 | 
			
		||||
  return fd_out_length(&fdo);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*** Log output
 | 
			
		||||
 ***/
 | 
			
		||||
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <sys/mman.h>
 | 
			
		||||
#include <sys/uio.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
static pthread_mutex_t gAbortMsgLock = PTHREAD_MUTEX_INITIALIZER;
 | 
			
		||||
static pthread_mutex_t gLogInitializationLock = PTHREAD_MUTEX_INITIALIZER;
 | 
			
		||||
 | 
			
		||||
int __libc_format_log_va_list(int priority, const char* tag, const char* fmt, va_list args) {
 | 
			
		||||
  char buf[1024];
 | 
			
		||||
  int buf_strlen = vformat_buffer(buf, sizeof(buf), fmt, args);
 | 
			
		||||
__LIBC_HIDDEN__ abort_msg_t** __abort_message_ptr; // Accessible to __libc_init_common.
 | 
			
		||||
 | 
			
		||||
  static int main_log_fd = -1;
 | 
			
		||||
  if (main_log_fd == -1) {
 | 
			
		||||
    ScopedPthreadMutexLocker locker(&gLogInitializationLock);
 | 
			
		||||
    main_log_fd = TEMP_FAILURE_RETRY(open("/dev/log/main", O_CLOEXEC | O_WRONLY));
 | 
			
		||||
    if (main_log_fd == -1) {
 | 
			
		||||
      return -1;
 | 
			
		||||
// Must be kept in sync with frameworks/base/core/java/android/util/EventLog.java.
 | 
			
		||||
enum AndroidEventLogType {
 | 
			
		||||
  EVENT_TYPE_INT      = 0,
 | 
			
		||||
  EVENT_TYPE_LONG     = 1,
 | 
			
		||||
  EVENT_TYPE_STRING   = 2,
 | 
			
		||||
  EVENT_TYPE_LIST     = 3,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct BufferOutputStream {
 | 
			
		||||
 public:
 | 
			
		||||
  BufferOutputStream(char* buffer, size_t size) : total(0) {
 | 
			
		||||
    buffer_ = buffer;
 | 
			
		||||
    end_ = buffer + size - 1;
 | 
			
		||||
    pos_ = buffer_;
 | 
			
		||||
    pos_[0] = '\0';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ~BufferOutputStream() {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void Send(const char* data, int len) {
 | 
			
		||||
    if (len < 0) {
 | 
			
		||||
      len = strlen(data);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    while (len > 0) {
 | 
			
		||||
      int avail = end_ - pos_;
 | 
			
		||||
      if (avail == 0) {
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      if (avail > len) {
 | 
			
		||||
        avail = len;
 | 
			
		||||
      }
 | 
			
		||||
      memcpy(pos_, data, avail);
 | 
			
		||||
      pos_ += avail;
 | 
			
		||||
      pos_[0] = '\0';
 | 
			
		||||
      len -= avail;
 | 
			
		||||
      total += avail;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  struct iovec vec[3];
 | 
			
		||||
  vec[0].iov_base = &priority;
 | 
			
		||||
  vec[0].iov_len = 1;
 | 
			
		||||
  vec[1].iov_base = const_cast<char*>(tag);
 | 
			
		||||
  vec[1].iov_len = strlen(tag) + 1;
 | 
			
		||||
  vec[2].iov_base = const_cast<char*>(buf);
 | 
			
		||||
  vec[2].iov_len = buf_strlen + 1;
 | 
			
		||||
  int total;
 | 
			
		||||
 | 
			
		||||
  return TEMP_FAILURE_RETRY(writev(main_log_fd, vec, 3));
 | 
			
		||||
}
 | 
			
		||||
 private:
 | 
			
		||||
  char* buffer_;
 | 
			
		||||
  char* pos_;
 | 
			
		||||
  char* end_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int __libc_format_log(int priority, const char* tag, const char* format, ...) {
 | 
			
		||||
  va_list args;
 | 
			
		||||
  va_start(args, format);
 | 
			
		||||
  int result = __libc_format_log_va_list(priority, tag, format, args);
 | 
			
		||||
  va_end(args);
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
struct FdOutputStream {
 | 
			
		||||
 public:
 | 
			
		||||
  FdOutputStream(int fd) : total(0), fd_(fd) {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void Send(const char* data, int len) {
 | 
			
		||||
    if (len < 0) {
 | 
			
		||||
      len = strlen(data);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    while (len > 0) {
 | 
			
		||||
      int rc = TEMP_FAILURE_RETRY(write(fd_, data, len));
 | 
			
		||||
      if (rc == -1) {
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      data += rc;
 | 
			
		||||
      len -= rc;
 | 
			
		||||
      total += rc;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  int total;
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  int fd_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*** formatted output implementation
 | 
			
		||||
 ***/
 | 
			
		||||
@@ -263,9 +131,7 @@ int __libc_format_log(int priority, const char* tag, const char* format, ...) {
 | 
			
		||||
 *
 | 
			
		||||
 * NOTE: Does *not* handle a sign prefix.
 | 
			
		||||
 */
 | 
			
		||||
static unsigned
 | 
			
		||||
parse_decimal(const char *format, int *ppos)
 | 
			
		||||
{
 | 
			
		||||
static unsigned parse_decimal(const char *format, int *ppos) {
 | 
			
		||||
    const char* p = format + *ppos;
 | 
			
		||||
    unsigned result = 0;
 | 
			
		||||
 | 
			
		||||
@@ -273,8 +139,9 @@ parse_decimal(const char *format, int *ppos)
 | 
			
		||||
        int ch = *p;
 | 
			
		||||
        unsigned d = (unsigned)(ch - '0');
 | 
			
		||||
 | 
			
		||||
        if (d >= 10U)
 | 
			
		||||
        if (d >= 10U) {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        result = result*10 + d;
 | 
			
		||||
        p++;
 | 
			
		||||
@@ -341,10 +208,25 @@ static void format_integer(char* buf, size_t buf_size, uint64_t value, char conv
 | 
			
		||||
  format_unsigned(buf, buf_size, value, base, caps);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Out>
 | 
			
		||||
static void SendRepeat(Out& o, char ch, int count) {
 | 
			
		||||
  char pad[8];
 | 
			
		||||
  memset(pad, ch, sizeof(pad));
 | 
			
		||||
 | 
			
		||||
  const int pad_size = static_cast<int>(sizeof(pad));
 | 
			
		||||
  while (count > 0) {
 | 
			
		||||
    int avail = count;
 | 
			
		||||
    if (avail > pad_size) {
 | 
			
		||||
      avail = pad_size;
 | 
			
		||||
    }
 | 
			
		||||
    o.Send(pad, avail);
 | 
			
		||||
    count -= avail;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Perform formatted output to an output target 'o' */
 | 
			
		||||
static void
 | 
			
		||||
out_vformat(Out *o, const char *format, va_list args)
 | 
			
		||||
{
 | 
			
		||||
template <typename Out>
 | 
			
		||||
static void out_vformat(Out& o, const char* format, va_list args) {
 | 
			
		||||
    int nn = 0;
 | 
			
		||||
 | 
			
		||||
    for (;;) {
 | 
			
		||||
@@ -371,7 +253,7 @@ out_vformat(Out *o, const char *format, va_list args)
 | 
			
		||||
        } while (1);
 | 
			
		||||
 | 
			
		||||
        if (mm > nn) {
 | 
			
		||||
            out_send(o, format+nn, mm-nn);
 | 
			
		||||
            o.Send(format+nn, mm-nn);
 | 
			
		||||
            nn = mm;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -387,7 +269,7 @@ out_vformat(Out *o, const char *format, va_list args)
 | 
			
		||||
            c = format[nn++];
 | 
			
		||||
            if (c == '\0') {  /* single trailing '%' ? */
 | 
			
		||||
                c = '%';
 | 
			
		||||
                out_send(o, &c, 1);
 | 
			
		||||
                o.Send(&c, 1);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            else if (c == '0') {
 | 
			
		||||
@@ -508,28 +390,74 @@ out_vformat(Out *o, const char *format, va_list args)
 | 
			
		||||
 | 
			
		||||
        if (slen < width && !padLeft) {
 | 
			
		||||
            char padChar = padZero ? '0' : ' ';
 | 
			
		||||
            out_send_repeat(o, padChar, width - slen);
 | 
			
		||||
            SendRepeat(o, padChar, width - slen);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        out_send(o, str, slen);
 | 
			
		||||
        o.Send(str, slen);
 | 
			
		||||
 | 
			
		||||
        if (slen < width && padLeft) {
 | 
			
		||||
            char padChar = padZero ? '0' : ' ';
 | 
			
		||||
            out_send_repeat(o, padChar, width - slen);
 | 
			
		||||
            SendRepeat(o, padChar, width - slen);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// must be kept in sync with frameworks/base/core/java/android/util/EventLog.java
 | 
			
		||||
enum AndroidEventLogType {
 | 
			
		||||
  EVENT_TYPE_INT      = 0,
 | 
			
		||||
  EVENT_TYPE_LONG     = 1,
 | 
			
		||||
  EVENT_TYPE_STRING   = 2,
 | 
			
		||||
  EVENT_TYPE_LIST     = 3,
 | 
			
		||||
};
 | 
			
		||||
int __libc_format_buffer(char* buffer, size_t buffer_size, const char* format, ...) {
 | 
			
		||||
  BufferOutputStream os(buffer, buffer_size);
 | 
			
		||||
  va_list args;
 | 
			
		||||
  va_start(args, format);
 | 
			
		||||
  out_vformat(os, format, args);
 | 
			
		||||
  va_end(args);
 | 
			
		||||
  return os.total;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int __libc_format_fd(int fd, const char* format, ...) {
 | 
			
		||||
  FdOutputStream os(fd);
 | 
			
		||||
  va_list args;
 | 
			
		||||
  va_start(args, format);
 | 
			
		||||
  out_vformat(os, format, args);
 | 
			
		||||
  va_end(args);
 | 
			
		||||
  return os.total;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int __libc_write_log(int priority, const char* tag, const char* msg) {
 | 
			
		||||
  static int main_log_fd = -1;
 | 
			
		||||
  if (main_log_fd == -1) {
 | 
			
		||||
    ScopedPthreadMutexLocker locker(&gLogInitializationLock);
 | 
			
		||||
    main_log_fd = TEMP_FAILURE_RETRY(open("/dev/log/main", O_CLOEXEC | O_WRONLY));
 | 
			
		||||
    if (main_log_fd == -1) {
 | 
			
		||||
      return -1;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  iovec vec[3];
 | 
			
		||||
  vec[0].iov_base = &priority;
 | 
			
		||||
  vec[0].iov_len = 1;
 | 
			
		||||
  vec[1].iov_base = const_cast<char*>(tag);
 | 
			
		||||
  vec[1].iov_len = strlen(tag) + 1;
 | 
			
		||||
  vec[2].iov_base = const_cast<char*>(msg);
 | 
			
		||||
  vec[2].iov_len = strlen(msg) + 1;
 | 
			
		||||
 | 
			
		||||
  return TEMP_FAILURE_RETRY(writev(main_log_fd, vec, 3));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int __libc_format_log_va_list(int priority, const char* tag, const char* format, va_list args) {
 | 
			
		||||
  char buffer[1024];
 | 
			
		||||
  BufferOutputStream os(buffer, sizeof(buffer));
 | 
			
		||||
  out_vformat(os, format, args);
 | 
			
		||||
  return __libc_write_log(priority, tag, buffer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int __libc_format_log(int priority, const char* tag, const char* format, ...) {
 | 
			
		||||
  va_list args;
 | 
			
		||||
  va_start(args, format);
 | 
			
		||||
  int result = __libc_format_log_va_list(priority, tag, format, args);
 | 
			
		||||
  va_end(args);
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int __libc_android_log_event(int32_t tag, char type, const void* payload, size_t len) {
 | 
			
		||||
  struct iovec vec[3];
 | 
			
		||||
  iovec vec[3];
 | 
			
		||||
  vec[0].iov_base = &tag;
 | 
			
		||||
  vec[0].iov_len = sizeof(tag);
 | 
			
		||||
  vec[1].iov_base = &type;
 | 
			
		||||
@@ -554,9 +482,45 @@ void __libc_android_log_event_uid(int32_t tag) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void __fortify_chk_fail(const char *msg, uint32_t tag) {
 | 
			
		||||
  __libc_format_log(ANDROID_LOG_FATAL, "libc", "FORTIFY_SOURCE: %s. Calling abort().\n", msg);
 | 
			
		||||
  if (tag != 0) {
 | 
			
		||||
    __libc_android_log_event_uid(tag);
 | 
			
		||||
  }
 | 
			
		||||
  __libc_fatal("FORTIFY_SOURCE: %s. Calling abort().", msg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void __libc_fatal(const char* format, ...) {
 | 
			
		||||
  char msg[1024];
 | 
			
		||||
  BufferOutputStream os(msg, sizeof(msg));
 | 
			
		||||
  va_list args;
 | 
			
		||||
  va_start(args, format);
 | 
			
		||||
  out_vformat(os, format, args);
 | 
			
		||||
  va_end(args);
 | 
			
		||||
 | 
			
		||||
  // TODO: log to stderr for the benefit of "adb shell" users.
 | 
			
		||||
 | 
			
		||||
  // Log to the log for the benefit of regular app developers (whose stdout and stderr are closed).
 | 
			
		||||
  __libc_write_log(ANDROID_LOG_FATAL, "libc", msg);
 | 
			
		||||
 | 
			
		||||
  __libc_set_abort_message(msg);
 | 
			
		||||
 | 
			
		||||
  abort();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void __libc_set_abort_message(const char* msg) {
 | 
			
		||||
  size_t size = sizeof(abort_msg_t) + strlen(msg) + 1;
 | 
			
		||||
  void* map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
 | 
			
		||||
  if (map == MAP_FAILED) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (__abort_message_ptr != NULL) {
 | 
			
		||||
    ScopedPthreadMutexLocker locker(&gAbortMsgLock);
 | 
			
		||||
    if (*__abort_message_ptr != NULL) {
 | 
			
		||||
      munmap(*__abort_message_ptr, (*__abort_message_ptr)->size);
 | 
			
		||||
    }
 | 
			
		||||
    abort_msg_t* new_abort_message = reinterpret_cast<abort_msg_t*>(map);
 | 
			
		||||
    new_abort_message->size = size;
 | 
			
		||||
    strcpy(new_abort_message->msg, msg);
 | 
			
		||||
    *__abort_message_ptr = new_abort_message;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -524,7 +524,7 @@ static pthread_once_t  malloc_fini_once_ctl = PTHREAD_ONCE_INIT;
 | 
			
		||||
 * This routine is called from __libc_init routines implemented
 | 
			
		||||
 * in libc_init_static.c and libc_init_dynamic.c files.
 | 
			
		||||
 */
 | 
			
		||||
extern "C" void malloc_debug_init() {
 | 
			
		||||
extern "C" __LIBC_HIDDEN__ void malloc_debug_init() {
 | 
			
		||||
    /* We need to initialize malloc iff we implement here custom
 | 
			
		||||
     * malloc routines (i.e. USE_DL_PREFIX is defined) for libc.so */
 | 
			
		||||
#if defined(USE_DL_PREFIX) && !defined(LIBC_STATIC)
 | 
			
		||||
@@ -534,7 +534,7 @@ extern "C" void malloc_debug_init() {
 | 
			
		||||
#endif  // USE_DL_PREFIX && !LIBC_STATIC
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern "C" void malloc_debug_fini() {
 | 
			
		||||
extern "C" __LIBC_HIDDEN__ void malloc_debug_fini() {
 | 
			
		||||
    /* We need to finalize malloc iff we implement here custom
 | 
			
		||||
     * malloc routines (i.e. USE_DL_PREFIX is defined) for libc.so */
 | 
			
		||||
#if defined(USE_DL_PREFIX) && !defined(LIBC_STATIC)
 | 
			
		||||
 
 | 
			
		||||
@@ -600,7 +600,7 @@ int malloc_debug_initialize() {
 | 
			
		||||
        error_log("Unable to open /dev/qemu_trace");
 | 
			
		||||
        return -1;
 | 
			
		||||
    } else {
 | 
			
		||||
        qtrace = mmap(0, PAGESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
 | 
			
		||||
        qtrace = mmap(NULL, PAGESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
 | 
			
		||||
        close(fd);
 | 
			
		||||
 | 
			
		||||
        if (qtrace == MAP_FAILED) {
 | 
			
		||||
 
 | 
			
		||||
@@ -52,7 +52,7 @@ int open(const char *pathname, int flags, ...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int __open_2(const char *pathname, int flags) {
 | 
			
		||||
    if (flags & O_CREAT) {
 | 
			
		||||
    if (__predict_false(flags & O_CREAT)) {
 | 
			
		||||
        __fortify_chk_fail("open(O_CREAT) called without specifying a mode", 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -153,6 +153,7 @@ int pthread_create(pthread_t* thread_out, pthread_attr_t const* attr,
 | 
			
		||||
 | 
			
		||||
  pthread_internal_t* thread = reinterpret_cast<pthread_internal_t*>(calloc(sizeof(*thread), 1));
 | 
			
		||||
  if (thread == NULL) {
 | 
			
		||||
    __libc_format_log(ANDROID_LOG_WARN, "libc", "pthread_create failed: couldn't allocate thread");
 | 
			
		||||
    return EAGAIN;
 | 
			
		||||
  }
 | 
			
		||||
  thread->allocated_on_heap = true;
 | 
			
		||||
@@ -172,6 +173,7 @@ int pthread_create(pthread_t* thread_out, pthread_attr_t const* attr,
 | 
			
		||||
    thread->attr.stack_base = __create_thread_stack(stack_size, thread->attr.guard_size);
 | 
			
		||||
    if (thread->attr.stack_base == NULL) {
 | 
			
		||||
      free(thread);
 | 
			
		||||
      __libc_format_log(ANDROID_LOG_WARN, "libc", "pthread_create failed: couldn't allocate %zd-byte stack", stack_size);
 | 
			
		||||
      return EAGAIN;
 | 
			
		||||
    }
 | 
			
		||||
  } else {
 | 
			
		||||
@@ -203,6 +205,7 @@ int pthread_create(pthread_t* thread_out, pthread_attr_t const* attr,
 | 
			
		||||
      munmap(thread->attr.stack_base, stack_size);
 | 
			
		||||
    }
 | 
			
		||||
    free(thread);
 | 
			
		||||
    __libc_format_log(ANDROID_LOG_WARN, "libc", "pthread_create failed: clone failed: %s", strerror(errno));
 | 
			
		||||
    return clone_errno;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										45
									
								
								libc/bionic/sched_getaffinity.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								libc/bionic/sched_getaffinity.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2010 The Android Open Source Project
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions
 | 
			
		||||
 * are met:
 | 
			
		||||
 *  * Redistributions of source code must retain the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *  * Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in
 | 
			
		||||
 *    the documentation and/or other materials provided with the
 | 
			
		||||
 *    distribution.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 | 
			
		||||
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
			
		||||
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 | 
			
		||||
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 | 
			
		||||
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 | 
			
		||||
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 | 
			
		||||
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 | 
			
		||||
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define _GNU_SOURCE 1
 | 
			
		||||
#include <sched.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
extern "C" int __sched_getaffinity(pid_t, size_t, cpu_set_t*);
 | 
			
		||||
 | 
			
		||||
int sched_getaffinity(pid_t pid, size_t set_size, cpu_set_t* set) {
 | 
			
		||||
  int rc = __sched_getaffinity(pid, set_size, set);
 | 
			
		||||
  if (rc == -1) {
 | 
			
		||||
      return -1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Clear any bytes the kernel didn't touch.
 | 
			
		||||
  // (The kernel returns the number of bytes written on success.)
 | 
			
		||||
  memset(reinterpret_cast<char*>(set) + rc, 0, set_size - rc);
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/*	$OpenBSD: index.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */
 | 
			
		||||
/*-
 | 
			
		||||
 * Copyright (c) 1990 The Regents of the University of California.
 | 
			
		||||
 * All rights reserved.
 | 
			
		||||
@@ -31,21 +30,21 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "libc_logging.h"
 | 
			
		||||
 | 
			
		||||
char *
 | 
			
		||||
__strchr_chk(const char *p, int ch, size_t s_len)
 | 
			
		||||
{
 | 
			
		||||
	for (;; ++p, s_len--) {
 | 
			
		||||
		if (s_len == 0)
 | 
			
		||||
			__fortify_chk_fail("strchr read beyond buffer", 0);
 | 
			
		||||
		if (*p == (char) ch)
 | 
			
		||||
			return((char *)p);
 | 
			
		||||
		if (!*p)
 | 
			
		||||
			return((char *)NULL);
 | 
			
		||||
	}
 | 
			
		||||
	/* NOTREACHED */
 | 
			
		||||
extern "C" char* __strchr_chk(const char* p, int ch, size_t s_len) {
 | 
			
		||||
  for (;; ++p, s_len--) {
 | 
			
		||||
    if (__predict_false(s_len == 0)) {
 | 
			
		||||
      __fortify_chk_fail("read beyond buffer", 0);
 | 
			
		||||
    }
 | 
			
		||||
    if (*p == static_cast<char>(ch)) {
 | 
			
		||||
      return const_cast<char*>(p);
 | 
			
		||||
    }
 | 
			
		||||
    if (*p == '\0') {
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  /* NOTREACHED */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *
 | 
			
		||||
strchr(const char *p, int ch) {
 | 
			
		||||
    return __strchr_chk(p, ch, __BIONIC_FORTIFY_UNKNOWN_SIZE);
 | 
			
		||||
extern "C" char* strchr(const char* p, int ch) {
 | 
			
		||||
  return __strchr_chk(p, ch, __BIONIC_FORTIFY_UNKNOWN_SIZE);
 | 
			
		||||
}
 | 
			
		||||
@@ -106,7 +106,7 @@ int __system_properties_init(void)
 | 
			
		||||
        goto cleanup;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    prop_area *pa = mmap(0, fd_stat.st_size, PROT_READ, MAP_SHARED, fd, 0);
 | 
			
		||||
    prop_area *pa = mmap(NULL, fd_stat.st_size, PROT_READ, MAP_SHARED, fd, 0);
 | 
			
		||||
 | 
			
		||||
    if (pa == MAP_FAILED) {
 | 
			
		||||
        goto cleanup;
 | 
			
		||||
@@ -150,7 +150,7 @@ const prop_info *__system_property_find(const char *name)
 | 
			
		||||
    while(count--) {
 | 
			
		||||
        unsigned entry = *toc++;
 | 
			
		||||
        if(TOC_NAME_LEN(entry) != len) continue;
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        pi = TOC_TO_INFO(pa, entry);
 | 
			
		||||
        if(memcmp(name, pi->name, len)) continue;
 | 
			
		||||
 | 
			
		||||
@@ -163,7 +163,7 @@ const prop_info *__system_property_find(const char *name)
 | 
			
		||||
int __system_property_read(const prop_info *pi, char *name, char *value)
 | 
			
		||||
{
 | 
			
		||||
    unsigned serial, len;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    for(;;) {
 | 
			
		||||
        serial = pi->serial;
 | 
			
		||||
        while(SERIAL_DIRTY(serial)) {
 | 
			
		||||
 
 | 
			
		||||
@@ -466,8 +466,7 @@ __attribute__((__format__ (printf, 3, 0)))
 | 
			
		||||
__attribute__((__nonnull__ (3)))
 | 
			
		||||
int vsnprintf(char *dest, size_t size, const char *format, __va_list ap)
 | 
			
		||||
{
 | 
			
		||||
    return __builtin___vsnprintf_chk(dest, size, 0,
 | 
			
		||||
        __builtin_object_size(dest, 0), format, ap);
 | 
			
		||||
    return __builtin___vsnprintf_chk(dest, size, 0, __bos(dest), format, ap);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__BIONIC_FORTIFY_INLINE
 | 
			
		||||
@@ -475,8 +474,7 @@ __attribute__((__format__ (printf, 2, 0)))
 | 
			
		||||
__attribute__((__nonnull__ (2)))
 | 
			
		||||
int vsprintf(char *dest, const char *format, __va_list ap)
 | 
			
		||||
{
 | 
			
		||||
    return __builtin___vsprintf_chk(dest, 0,
 | 
			
		||||
        __builtin_object_size(dest, 0), format, ap);
 | 
			
		||||
    return __builtin___vsprintf_chk(dest, 0, __bos(dest), format, ap);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__BIONIC_FORTIFY_INLINE
 | 
			
		||||
@@ -485,7 +483,7 @@ __attribute__((__nonnull__ (3)))
 | 
			
		||||
int snprintf(char *str, size_t size, const char *format, ...)
 | 
			
		||||
{
 | 
			
		||||
    return __builtin___snprintf_chk(str, size, 0,
 | 
			
		||||
        __builtin_object_size(str, 0), format, __builtin_va_arg_pack());
 | 
			
		||||
        __bos(str), format, __builtin_va_arg_pack());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__BIONIC_FORTIFY_INLINE
 | 
			
		||||
@@ -494,7 +492,7 @@ __attribute__((__nonnull__ (2)))
 | 
			
		||||
int sprintf(char *dest, const char *format, ...)
 | 
			
		||||
{
 | 
			
		||||
    return __builtin___sprintf_chk(dest, 0,
 | 
			
		||||
        __builtin_object_size(dest, 0), format, __builtin_va_arg_pack());
 | 
			
		||||
        __bos(dest), format, __builtin_va_arg_pack());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern char *__fgets_real(char *, int, FILE *)
 | 
			
		||||
@@ -508,7 +506,7 @@ extern char *__fgets_chk(char *, int, FILE *, size_t);
 | 
			
		||||
__BIONIC_FORTIFY_INLINE
 | 
			
		||||
char *fgets(char *dest, int size, FILE *stream)
 | 
			
		||||
{
 | 
			
		||||
    size_t bos = __builtin_object_size(dest, 0);
 | 
			
		||||
    size_t bos = __bos(dest);
 | 
			
		||||
 | 
			
		||||
    // Compiler can prove, at compile time, that the passed in size
 | 
			
		||||
    // is always negative. Force a compiler error.
 | 
			
		||||
 
 | 
			
		||||
@@ -34,11 +34,11 @@
 | 
			
		||||
 | 
			
		||||
__BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
extern void*  memccpy(void *, const void *, int, size_t);
 | 
			
		||||
extern void*  memccpy(void* __restrict, const void* __restrict, int, size_t);
 | 
			
		||||
extern void*  memchr(const void *, int, size_t) __purefunc;
 | 
			
		||||
extern void*  memrchr(const void *, int, size_t) __purefunc;
 | 
			
		||||
extern int    memcmp(const void *, const void *, size_t) __purefunc;
 | 
			
		||||
extern void*  memcpy(void *, const void *, size_t);
 | 
			
		||||
extern void*  memcpy(void* __restrict, const void* __restrict, size_t);
 | 
			
		||||
extern void*  memmove(void *, const void *, size_t);
 | 
			
		||||
extern void*  memset(void *, int, size_t);
 | 
			
		||||
extern void*  memmem(const void *, size_t, const void *, size_t) __purefunc;
 | 
			
		||||
@@ -50,8 +50,8 @@ extern char*  strrchr(const char *, int) __purefunc;
 | 
			
		||||
 | 
			
		||||
extern size_t strlen(const char *) __purefunc;
 | 
			
		||||
extern int    strcmp(const char *, const char *) __purefunc;
 | 
			
		||||
extern char*  strcpy(char *, const char *);
 | 
			
		||||
extern char*  strcat(char *, const char *);
 | 
			
		||||
extern char*  strcpy(char* __restrict, const char* __restrict);
 | 
			
		||||
extern char*  strcat(char* __restrict, const char* __restrict);
 | 
			
		||||
 | 
			
		||||
extern int    strcasecmp(const char *, const char *) __purefunc;
 | 
			
		||||
extern int    strncasecmp(const char *, const char *, size_t) __purefunc;
 | 
			
		||||
@@ -59,30 +59,30 @@ extern char*  strdup(const char *);
 | 
			
		||||
 | 
			
		||||
extern char*  strstr(const char *, const char *) __purefunc;
 | 
			
		||||
extern char*  strcasestr(const char *haystack, const char *needle) __purefunc;
 | 
			
		||||
extern char*  strtok(char *, const char *);
 | 
			
		||||
extern char*  strtok_r(char *, const char *, char**);
 | 
			
		||||
extern char*  strtok(char* __restrict, const char* __restrict);
 | 
			
		||||
extern char*  strtok_r(char* __restrict, const char* __restrict, char** __restrict);
 | 
			
		||||
 | 
			
		||||
extern char*  strerror(int);
 | 
			
		||||
extern int    strerror_r(int errnum, char *buf, size_t n);
 | 
			
		||||
 | 
			
		||||
extern size_t strnlen(const char *, size_t) __purefunc;
 | 
			
		||||
extern char*  strncat(char *, const char *, size_t);
 | 
			
		||||
extern char*  strncat(char* __restrict, const char* __restrict, size_t);
 | 
			
		||||
extern char*  strndup(const char *, size_t);
 | 
			
		||||
extern int    strncmp(const char *, const char *, size_t) __purefunc;
 | 
			
		||||
extern char*  strncpy(char *, const char *, size_t);
 | 
			
		||||
extern char*  strncpy(char* __restrict, const char* __restrict, size_t);
 | 
			
		||||
 | 
			
		||||
extern size_t strlcat(char *, const char *, size_t);
 | 
			
		||||
extern size_t strlcpy(char *, const char *, size_t);
 | 
			
		||||
extern size_t strlcat(char* __restrict, const char* __restrict, size_t);
 | 
			
		||||
extern size_t strlcpy(char* __restrict, const char* __restrict, size_t);
 | 
			
		||||
 | 
			
		||||
extern size_t strcspn(const char *, const char *) __purefunc;
 | 
			
		||||
extern char*  strpbrk(const char *, const char *) __purefunc;
 | 
			
		||||
extern char*  strsep(char **, const char *);
 | 
			
		||||
extern char*  strsep(char** __restrict, const char* __restrict);
 | 
			
		||||
extern size_t strspn(const char *, const char *);
 | 
			
		||||
 | 
			
		||||
extern char*  strsignal(int  sig);
 | 
			
		||||
 | 
			
		||||
extern int    strcoll(const char *, const char *) __purefunc;
 | 
			
		||||
extern size_t strxfrm(char *, const char *, size_t);
 | 
			
		||||
extern size_t strxfrm(char* __restrict, const char* __restrict, size_t);
 | 
			
		||||
 | 
			
		||||
#if defined(__BIONIC_FORTIFY)
 | 
			
		||||
 | 
			
		||||
@@ -92,7 +92,7 @@ extern void __memcpy_src_size_error()
 | 
			
		||||
    __attribute__((__error__("memcpy called with size bigger than source")));
 | 
			
		||||
 | 
			
		||||
__BIONIC_FORTIFY_INLINE
 | 
			
		||||
void *memcpy (void *dest, const void *src, size_t copy_amount) {
 | 
			
		||||
void *memcpy (void* __restrict dest, const void* __restrict src, size_t copy_amount) {
 | 
			
		||||
    char *d = (char *) dest;
 | 
			
		||||
    const char *s = (const char *) src;
 | 
			
		||||
    size_t s_len = __builtin_object_size(s, 0);
 | 
			
		||||
@@ -115,23 +115,30 @@ void *memmove (void *dest, const void *src, size_t len) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__BIONIC_FORTIFY_INLINE
 | 
			
		||||
char *strcpy(char *dest, const char *src) {
 | 
			
		||||
    return __builtin___strcpy_chk(dest, src, __builtin_object_size (dest, 0));
 | 
			
		||||
char *strcpy(char* __restrict dest, const char* __restrict src) {
 | 
			
		||||
    return __builtin___strcpy_chk(dest, src, __bos(dest));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern void __strncpy_error()
 | 
			
		||||
    __attribute__((__error__("strncpy called with size bigger than buffer")));
 | 
			
		||||
 | 
			
		||||
__BIONIC_FORTIFY_INLINE
 | 
			
		||||
char *strncpy(char* __restrict dest, const char* __restrict src, size_t n) {
 | 
			
		||||
    size_t bos = __bos(dest);
 | 
			
		||||
    if (__builtin_constant_p(n) && (n > bos)) {
 | 
			
		||||
        __strncpy_error();
 | 
			
		||||
    }
 | 
			
		||||
    return __builtin___strncpy_chk(dest, src, n, bos);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__BIONIC_FORTIFY_INLINE
 | 
			
		||||
char *strncpy(char *dest, const char *src, size_t n) {
 | 
			
		||||
    return __builtin___strncpy_chk(dest, src, n, __builtin_object_size (dest, 0));
 | 
			
		||||
char *strcat(char* __restrict dest, const char* __restrict src) {
 | 
			
		||||
    return __builtin___strcat_chk(dest, src, __bos(dest));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__BIONIC_FORTIFY_INLINE
 | 
			
		||||
char *strcat(char *dest, const char *src) {
 | 
			
		||||
    return __builtin___strcat_chk(dest, src, __builtin_object_size (dest, 0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__BIONIC_FORTIFY_INLINE
 | 
			
		||||
char *strncat(char *dest, const char *src, size_t n) {
 | 
			
		||||
    return __builtin___strncat_chk(dest, src, n, __builtin_object_size (dest, 0));
 | 
			
		||||
char *strncat(char* __restrict dest, const char* __restrict src, size_t n) {
 | 
			
		||||
    return __builtin___strncat_chk(dest, src, n, __bos(dest));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__BIONIC_FORTIFY_INLINE
 | 
			
		||||
@@ -139,15 +146,15 @@ void *memset (void *s, int c, size_t n) {
 | 
			
		||||
    return __builtin___memset_chk(s, c, n, __builtin_object_size (s, 0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern size_t __strlcpy_real(char *, const char *, size_t)
 | 
			
		||||
extern size_t __strlcpy_real(char* __restrict, const char* __restrict, size_t)
 | 
			
		||||
    __asm__(__USER_LABEL_PREFIX__ "strlcpy");
 | 
			
		||||
extern void __strlcpy_error()
 | 
			
		||||
    __attribute__((__error__("strlcpy called with size bigger than buffer")));
 | 
			
		||||
extern size_t __strlcpy_chk(char *, const char *, size_t, size_t);
 | 
			
		||||
 | 
			
		||||
__BIONIC_FORTIFY_INLINE
 | 
			
		||||
size_t strlcpy(char *dest, const char *src, size_t size) {
 | 
			
		||||
    size_t bos = __builtin_object_size(dest, 0);
 | 
			
		||||
size_t strlcpy(char* __restrict dest, const char* __restrict src, size_t size) {
 | 
			
		||||
    size_t bos = __bos(dest);
 | 
			
		||||
 | 
			
		||||
    // Compiler doesn't know destination size. Don't call __strlcpy_chk
 | 
			
		||||
    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
 | 
			
		||||
@@ -169,16 +176,16 @@ size_t strlcpy(char *dest, const char *src, size_t size) {
 | 
			
		||||
    return __strlcpy_chk(dest, src, size, bos);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern size_t __strlcat_real(char *, const char *, size_t)
 | 
			
		||||
extern size_t __strlcat_real(char* __restrict, const char* __restrict, size_t)
 | 
			
		||||
    __asm__(__USER_LABEL_PREFIX__ "strlcat");
 | 
			
		||||
extern void __strlcat_error()
 | 
			
		||||
    __attribute__((__error__("strlcat called with size bigger than buffer")));
 | 
			
		||||
extern size_t __strlcat_chk(char *, const char *, size_t, size_t);
 | 
			
		||||
extern size_t __strlcat_chk(char* __restrict, const char* __restrict, size_t, size_t);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
__BIONIC_FORTIFY_INLINE
 | 
			
		||||
size_t strlcat(char *dest, const char *src, size_t size) {
 | 
			
		||||
    size_t bos = __builtin_object_size(dest, 0);
 | 
			
		||||
size_t strlcat(char* __restrict dest, const char* __restrict src, size_t size) {
 | 
			
		||||
    size_t bos = __bos(dest);
 | 
			
		||||
 | 
			
		||||
    // Compiler doesn't know destination size. Don't call __strlcat_chk
 | 
			
		||||
    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
 | 
			
		||||
@@ -204,7 +211,7 @@ extern size_t __strlen_chk(const char *, size_t);
 | 
			
		||||
 | 
			
		||||
__BIONIC_FORTIFY_INLINE
 | 
			
		||||
size_t strlen(const char *s) {
 | 
			
		||||
    size_t bos = __builtin_object_size(s, 0);
 | 
			
		||||
    size_t bos = __bos(s);
 | 
			
		||||
 | 
			
		||||
    // Compiler doesn't know destination size. Don't call __strlen_chk
 | 
			
		||||
    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
 | 
			
		||||
@@ -223,7 +230,7 @@ extern char* __strchr_chk(const char *, int, size_t);
 | 
			
		||||
 | 
			
		||||
__BIONIC_FORTIFY_INLINE
 | 
			
		||||
char* strchr(const char *s, int c) {
 | 
			
		||||
    size_t bos = __builtin_object_size(s, 0);
 | 
			
		||||
    size_t bos = __bos(s);
 | 
			
		||||
 | 
			
		||||
    // Compiler doesn't know destination size. Don't call __strchr_chk
 | 
			
		||||
    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
 | 
			
		||||
@@ -242,7 +249,7 @@ extern char* __strrchr_chk(const char *, int, size_t);
 | 
			
		||||
 | 
			
		||||
__BIONIC_FORTIFY_INLINE
 | 
			
		||||
char* strrchr(const char *s, int c) {
 | 
			
		||||
    size_t bos = __builtin_object_size(s, 0);
 | 
			
		||||
    size_t bos = __bos(s);
 | 
			
		||||
 | 
			
		||||
    // Compiler doesn't know destination size. Don't call __strrchr_chk
 | 
			
		||||
    if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
 | 
			
		||||
 
 | 
			
		||||
@@ -517,6 +517,12 @@
 | 
			
		||||
 | 
			
		||||
#if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && defined(__OPTIMIZE__) && __OPTIMIZE__ > 0 && !defined(__clang__)
 | 
			
		||||
#define __BIONIC_FORTIFY 1
 | 
			
		||||
#if _FORTIFY_SOURCE == 2
 | 
			
		||||
#define __bos(s) __builtin_object_size((s), 1)
 | 
			
		||||
#else
 | 
			
		||||
#define __bos(s) __builtin_object_size((s), 0)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define __BIONIC_FORTIFY_INLINE \
 | 
			
		||||
    extern inline \
 | 
			
		||||
    __attribute__ ((always_inline)) \
 | 
			
		||||
 
 | 
			
		||||
@@ -33,17 +33,16 @@
 | 
			
		||||
 | 
			
		||||
__BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define  EFD_CLOEXEC   O_CLOEXEC
 | 
			
		||||
#define  EFD_NONBLOCK  O_NONBLOCK
 | 
			
		||||
#define EFD_CLOEXEC O_CLOEXEC
 | 
			
		||||
#define EFD_NONBLOCK O_NONBLOCK
 | 
			
		||||
 | 
			
		||||
/* type of event counter */
 | 
			
		||||
typedef uint64_t  eventfd_t;
 | 
			
		||||
typedef uint64_t eventfd_t;
 | 
			
		||||
 | 
			
		||||
extern int eventfd(unsigned int initval, int flags);
 | 
			
		||||
extern int eventfd(unsigned int initial_value, int flags);
 | 
			
		||||
 | 
			
		||||
/* Compatibility with GLibc */
 | 
			
		||||
extern int eventfd_read(int fd, eventfd_t *counter);
 | 
			
		||||
extern int eventfd_write(int fd, const eventfd_t counter);
 | 
			
		||||
extern int eventfd_read(int fd, eventfd_t* value);
 | 
			
		||||
extern int eventfd_write(int fd, eventfd_t value);
 | 
			
		||||
 | 
			
		||||
__END_DECLS
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,7 @@
 | 
			
		||||
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 | 
			
		||||
#include <linux/netfilter/x_tables.h>
 | 
			
		||||
#define IPT_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN
 | 
			
		||||
#define IPT_TABLE_MAXNAMELEN XT_FUNCTION_MAXNAMELEN
 | 
			
		||||
#define IPT_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN
 | 
			
		||||
#define ipt_match xt_match
 | 
			
		||||
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
 | 
			
		||||
#define ipt_target xt_target
 | 
			
		||||
 
 | 
			
		||||
@@ -1527,10 +1527,8 @@ _get_scope(const struct sockaddr *addr)
 | 
			
		||||
			return IPV6_ADDR_SCOPE_LINKLOCAL;
 | 
			
		||||
		} else {
 | 
			
		||||
			/*
 | 
			
		||||
			 * According to draft-ietf-6man-rfc3484-revise-01 section 2.3,
 | 
			
		||||
			 * it is best not to treat the private IPv4 ranges
 | 
			
		||||
			 * (10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16) as being
 | 
			
		||||
			 * in a special scope, so we don't.
 | 
			
		||||
			 * RFC 6724 section 3.2. Other IPv4 addresses, including private addresses
 | 
			
		||||
			 * and shared addresses (100.64.0.0/10), are assigned global scope.
 | 
			
		||||
			 */
 | 
			
		||||
			return IPV6_ADDR_SCOPE_GLOBAL;
 | 
			
		||||
		}
 | 
			
		||||
@@ -1559,7 +1557,7 @@ _get_scope(const struct sockaddr *addr)
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Get the label for a given IPv4/IPv6 address.
 | 
			
		||||
 * RFC 3484, section 2.1, plus changes from draft-ietf-6man-rfc3484-revise-01.
 | 
			
		||||
 * RFC 6724, section 2.1.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*ARGSUSED*/
 | 
			
		||||
@@ -1567,27 +1565,28 @@ static int
 | 
			
		||||
_get_label(const struct sockaddr *addr)
 | 
			
		||||
{
 | 
			
		||||
	if (addr->sa_family == AF_INET) {
 | 
			
		||||
		return 3;
 | 
			
		||||
		return 4;
 | 
			
		||||
	} else if (addr->sa_family == AF_INET6) {
 | 
			
		||||
		const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr;
 | 
			
		||||
		const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *) addr;
 | 
			
		||||
		if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr)) {
 | 
			
		||||
			return 0;
 | 
			
		||||
		} else if (IN6_IS_ADDR_ULA(&addr6->sin6_addr)) {
 | 
			
		||||
			return 1;
 | 
			
		||||
		} else if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) {
 | 
			
		||||
			return 3;
 | 
			
		||||
		} else if (IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) {
 | 
			
		||||
			return 4;
 | 
			
		||||
		} else if (IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) {
 | 
			
		||||
			return 2;
 | 
			
		||||
		} else if (IN6_IS_ADDR_TEREDO(&addr6->sin6_addr)) {
 | 
			
		||||
			return 5;
 | 
			
		||||
		} else if (IN6_IS_ADDR_ULA(&addr6->sin6_addr)) {
 | 
			
		||||
			return 13;
 | 
			
		||||
		} else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr)) {
 | 
			
		||||
			return 10;
 | 
			
		||||
			return 3;
 | 
			
		||||
		} else if (IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr)) {
 | 
			
		||||
			return 11;
 | 
			
		||||
		} else if (IN6_IS_ADDR_6BONE(&addr6->sin6_addr)) {
 | 
			
		||||
			return 12;
 | 
			
		||||
		} else {
 | 
			
		||||
			return 2;
 | 
			
		||||
			/* All other IPv6 addresses, including global unicast addresses. */
 | 
			
		||||
			return 1;
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		/*
 | 
			
		||||
@@ -1600,7 +1599,7 @@ _get_label(const struct sockaddr *addr)
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Get the precedence for a given IPv4/IPv6 address.
 | 
			
		||||
 * RFC 3484, section 2.1, plus changes from draft-ietf-6man-rfc3484-revise-01.
 | 
			
		||||
 * RFC 6724, section 2.1.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*ARGSUSED*/
 | 
			
		||||
@@ -1608,24 +1607,25 @@ static int
 | 
			
		||||
_get_precedence(const struct sockaddr *addr)
 | 
			
		||||
{
 | 
			
		||||
	if (addr->sa_family == AF_INET) {
 | 
			
		||||
		return 30;
 | 
			
		||||
		return 35;
 | 
			
		||||
	} else if (addr->sa_family == AF_INET6) {
 | 
			
		||||
		const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr;
 | 
			
		||||
		if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr)) {
 | 
			
		||||
			return 60;
 | 
			
		||||
		} else if (IN6_IS_ADDR_ULA(&addr6->sin6_addr)) {
 | 
			
		||||
			return 50;
 | 
			
		||||
		} else if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) {
 | 
			
		||||
			return 30;
 | 
			
		||||
			return 35;
 | 
			
		||||
		} else if (IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) {
 | 
			
		||||
			return 20;
 | 
			
		||||
			return 30;
 | 
			
		||||
		} else if (IN6_IS_ADDR_TEREDO(&addr6->sin6_addr)) {
 | 
			
		||||
			return 10;
 | 
			
		||||
			return 5;
 | 
			
		||||
		} else if (IN6_IS_ADDR_ULA(&addr6->sin6_addr)) {
 | 
			
		||||
			return 3;
 | 
			
		||||
		} else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr) ||
 | 
			
		||||
		           IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr) ||
 | 
			
		||||
		           IN6_IS_ADDR_6BONE(&addr6->sin6_addr)) {
 | 
			
		||||
			return 1;
 | 
			
		||||
		} else {
 | 
			
		||||
			/* All other IPv6 addresses, including global unicast addresses. */
 | 
			
		||||
			return 40;
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
@@ -1664,12 +1664,12 @@ _common_prefix_len(const struct in6_addr *a1, const struct in6_addr *a2)
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Compare two source/destination address pairs.
 | 
			
		||||
 * RFC 3484, section 6.
 | 
			
		||||
 * RFC 6724, section 6.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*ARGSUSED*/
 | 
			
		||||
static int
 | 
			
		||||
_rfc3484_compare(const void *ptr1, const void* ptr2)
 | 
			
		||||
_rfc6724_compare(const void *ptr1, const void* ptr2)
 | 
			
		||||
{
 | 
			
		||||
	const struct addrinfo_sort_elem *a1 = (const struct addrinfo_sort_elem *)ptr1;
 | 
			
		||||
	const struct addrinfo_sort_elem *a2 = (const struct addrinfo_sort_elem *)ptr2;
 | 
			
		||||
@@ -1740,7 +1740,7 @@ _rfc3484_compare(const void *ptr1, const void* ptr2)
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Rule 9: Use longest matching prefix.
 | 
			
		||||
         * We implement this for IPv6 only, as the rules in RFC 3484 don't seem
 | 
			
		||||
         * We implement this for IPv6 only, as the rules in RFC 6724 don't seem
 | 
			
		||||
         * to work very well directly applied to IPv4. (glibc uses information from
 | 
			
		||||
         * the routing table for a custom IPv4 implementation here.)
 | 
			
		||||
	 */
 | 
			
		||||
@@ -1820,13 +1820,13 @@ _find_src_addr(const struct sockaddr *addr, struct sockaddr *src_addr)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Sort the linked list starting at sentinel->ai_next in RFC3484 order.
 | 
			
		||||
 * Sort the linked list starting at sentinel->ai_next in RFC6724 order.
 | 
			
		||||
 * Will leave the list unchanged if an error occurs.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*ARGSUSED*/
 | 
			
		||||
static void
 | 
			
		||||
_rfc3484_sort(struct addrinfo *list_sentinel)
 | 
			
		||||
_rfc6724_sort(struct addrinfo *list_sentinel)
 | 
			
		||||
{
 | 
			
		||||
	struct addrinfo *cur;
 | 
			
		||||
	int nelem = 0, i;
 | 
			
		||||
@@ -1861,7 +1861,7 @@ _rfc3484_sort(struct addrinfo *list_sentinel)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Sort the addresses, and rearrange the linked list so it matches the sorted order. */
 | 
			
		||||
	qsort((void *)elems, nelem, sizeof(struct addrinfo_sort_elem), _rfc3484_compare);
 | 
			
		||||
	qsort((void *)elems, nelem, sizeof(struct addrinfo_sort_elem), _rfc6724_compare);
 | 
			
		||||
 | 
			
		||||
	list_sentinel->ai_next = elems[0].ai;
 | 
			
		||||
	for (i = 0; i < nelem - 1; ++i) {
 | 
			
		||||
@@ -2012,7 +2012,7 @@ _dns_getaddrinfo(void *rv, void	*cb_data, va_list ap)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_rfc3484_sort(&sentinel);
 | 
			
		||||
	_rfc6724_sort(&sentinel);
 | 
			
		||||
 | 
			
		||||
	__res_put_state(res);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,8 @@
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <sys/auxv.h>
 | 
			
		||||
 | 
			
		||||
struct abort_msg_t;
 | 
			
		||||
 | 
			
		||||
// When the kernel starts the dynamic linker, it passes a pointer to a block
 | 
			
		||||
// of memory containing argc, the argv array, the environment variable array,
 | 
			
		||||
// and the array of ELF aux vectors. This class breaks that block up into its
 | 
			
		||||
@@ -67,6 +69,8 @@ class KernelArgumentBlock {
 | 
			
		||||
  char** envp;
 | 
			
		||||
  Elf32_auxv_t* auxv;
 | 
			
		||||
 | 
			
		||||
  abort_msg_t** abort_message_ptr;
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  // Disallow copy and assignment.
 | 
			
		||||
  KernelArgumentBlock(const KernelArgumentBlock&);
 | 
			
		||||
 
 | 
			
		||||
@@ -67,6 +67,20 @@ enum {
 | 
			
		||||
  ANDROID_LOG_SILENT,     /* only for SetMinPriority(); must be last */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct abort_msg_t {
 | 
			
		||||
  size_t size;
 | 
			
		||||
  char msg[0];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
__LIBC_HIDDEN__ void __libc_set_abort_message(const char* msg);
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Formats a message to the log (priority 'fatal'), then aborts.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
__LIBC_HIDDEN__ __noreturn void __libc_fatal(const char* format, ...)
 | 
			
		||||
    __attribute__((__format__(printf, 1, 2)));
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Formatting routines for the C library's internal debugging.
 | 
			
		||||
// Unlike the usual alternatives, these don't allocate.
 | 
			
		||||
 
 | 
			
		||||
@@ -1,188 +0,0 @@
 | 
			
		||||
#!/usr/bin/python
 | 
			
		||||
#
 | 
			
		||||
# this tool is used to check that the syscall numbers that are in
 | 
			
		||||
# SYSCALLS.TXT correspond to those found in the Linux kernel sources
 | 
			
		||||
# for the arm, i386 and mips architectures
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
import sys, re, string, os, commands
 | 
			
		||||
from   bionic_utils import *
 | 
			
		||||
 | 
			
		||||
# change this if necessary
 | 
			
		||||
syscalls_txt = "SYSCALLS.TXT"
 | 
			
		||||
 | 
			
		||||
def usage():
 | 
			
		||||
    print "usage: checksyscalls [options] [kernel_headers_rootdir]"
 | 
			
		||||
    print "    options:    -v   enable verbose mode"
 | 
			
		||||
    sys.exit(1)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
linux_root    = None
 | 
			
		||||
syscalls_file = None
 | 
			
		||||
 | 
			
		||||
def parse_command_line(args):
 | 
			
		||||
    global linux_root, syscalls_file, verbose
 | 
			
		||||
 | 
			
		||||
    program = args[0]
 | 
			
		||||
    args    = args[1:]
 | 
			
		||||
    while len(args) > 0 and args[0][0] == "-":
 | 
			
		||||
        option = args[0][1:]
 | 
			
		||||
        args   = args[1:]
 | 
			
		||||
 | 
			
		||||
        if option == "v":
 | 
			
		||||
            D_setlevel(1)
 | 
			
		||||
        else:
 | 
			
		||||
            usage()
 | 
			
		||||
 | 
			
		||||
    if len(args) > 2:
 | 
			
		||||
        usage()
 | 
			
		||||
 | 
			
		||||
    if len(args) == 0:
 | 
			
		||||
        linux_root = find_kernel_headers()
 | 
			
		||||
        if linux_root == None:
 | 
			
		||||
            print "Could not locate original or system kernel headers root directory."
 | 
			
		||||
            print "Please specify one when calling this program, i.e. 'checksyscalls <headers-directory>'"
 | 
			
		||||
            sys.exit(1)
 | 
			
		||||
        print "using the following kernel headers root: '%s'" % linux_root
 | 
			
		||||
    else:
 | 
			
		||||
        linux_root = args[0]
 | 
			
		||||
        if not os.path.isdir(linux_root):
 | 
			
		||||
            print "the directory '%s' does not exist. aborting\n" % headers_root
 | 
			
		||||
            sys.exit(1)
 | 
			
		||||
 | 
			
		||||
parse_command_line(sys.argv)
 | 
			
		||||
 | 
			
		||||
syscalls_file = find_file_from_upwards(None, syscalls_txt)
 | 
			
		||||
if not syscalls_file:
 | 
			
		||||
    print "could not locate the %s file. Aborting" % syscalls_txt
 | 
			
		||||
    sys.exit(1)
 | 
			
		||||
 | 
			
		||||
print "parsing %s" % syscalls_file
 | 
			
		||||
 | 
			
		||||
# read the syscalls description file
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
parser = SysCallsTxtParser()
 | 
			
		||||
parser.parse_file(syscalls_file)
 | 
			
		||||
syscalls = parser.syscalls
 | 
			
		||||
 | 
			
		||||
re_nr_line       = re.compile( r"#define __NR_(\w*)\s*\(__NR_SYSCALL_BASE\+\s*(\w*)\)" )
 | 
			
		||||
re_nr_clock_line = re.compile( r"#define __NR_(\w*)\s*\(__NR_timer_create\+(\w*)\)" )
 | 
			
		||||
re_arm_nr_line   = re.compile( r"#define __ARM_NR_(\w*)\s*\(__ARM_NR_BASE\+\s*(\w*)\)" )
 | 
			
		||||
re_x86_line      = re.compile( r"#define __NR_(\w*)\s*([0-9]*)" )
 | 
			
		||||
re_mips_line     = re.compile( r"#define __NR_(\w*)\s*\(__NR_Linux\s*\+\s*([0-9]*)\)" )
 | 
			
		||||
 | 
			
		||||
# now read the Linux arm header
 | 
			
		||||
def process_nr_line(line,dict):
 | 
			
		||||
 | 
			
		||||
    m = re_mips_line.match(line)
 | 
			
		||||
    if m:
 | 
			
		||||
        if dict["Linux"]==4000:
 | 
			
		||||
            dict[m.group(1)] = int(m.group(2))
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    m = re_nr_line.match(line)
 | 
			
		||||
    if m:
 | 
			
		||||
        dict[m.group(1)] = int(m.group(2))
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    m = re_nr_clock_line.match(line)
 | 
			
		||||
    if m:
 | 
			
		||||
        dict[m.group(1)] = int(m.group(2)) + 259
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    m = re_arm_nr_line.match(line)
 | 
			
		||||
    if m:
 | 
			
		||||
        offset_str = m.group(2)
 | 
			
		||||
        #print "%s = %s" % (m.group(1), offset_str)
 | 
			
		||||
        base = 10
 | 
			
		||||
        if offset_str.lower().startswith("0x"):
 | 
			
		||||
          # Processing something similar to
 | 
			
		||||
          #   #define __ARM_NR_cmpxchg  (__ARM_NR_BASE+0x00fff0)
 | 
			
		||||
          base = 16
 | 
			
		||||
        dict["ARM_"+m.group(1)] = int(offset_str, base) + 0x0f0000
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    m = re_x86_line.match(line)
 | 
			
		||||
    if m:
 | 
			
		||||
        # try block because the ARM header has some #define _NR_XXXXX  /* nothing */
 | 
			
		||||
        try:
 | 
			
		||||
            #print "%s = %s" % (m.group(1), m.group(2))
 | 
			
		||||
            dict[m.group(1)] = int(m.group(2))
 | 
			
		||||
        except:
 | 
			
		||||
            pass
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def process_header(header_file,dict):
 | 
			
		||||
    fp = open(header_file)
 | 
			
		||||
    D("reading "+header_file)
 | 
			
		||||
    for line in fp.xreadlines():
 | 
			
		||||
        line = line.strip()
 | 
			
		||||
        if not line: continue
 | 
			
		||||
        process_nr_line(line,dict)
 | 
			
		||||
    fp.close()
 | 
			
		||||
 | 
			
		||||
arm_dict = {}
 | 
			
		||||
x86_dict = {}
 | 
			
		||||
mips_dict = {}
 | 
			
		||||
 | 
			
		||||
# remove trailing slash from the linux_root, if any
 | 
			
		||||
if linux_root[-1] == '/':
 | 
			
		||||
    linux_root = linux_root[:-1]
 | 
			
		||||
 | 
			
		||||
arm_unistd = find_arch_header(linux_root, "arm", "unistd.h")
 | 
			
		||||
if not arm_unistd:
 | 
			
		||||
    print "WEIRD: Could not locate the ARM unistd.h kernel header file,"
 | 
			
		||||
    print "maybe using a different set of kernel headers might help."
 | 
			
		||||
    sys.exit(1)
 | 
			
		||||
 | 
			
		||||
# on recent kernels, asm-i386 and asm-x64_64 have been merged into asm-x86
 | 
			
		||||
# with two distinct unistd_32.h and unistd_64.h definition files.
 | 
			
		||||
# take care of this here
 | 
			
		||||
#
 | 
			
		||||
x86_unistd = find_arch_header(linux_root, "i386", "unistd.h")
 | 
			
		||||
if not x86_unistd:
 | 
			
		||||
    x86_unistd = find_arch_header(linux_root, "x86", "unistd_32.h")
 | 
			
		||||
    if not x86_unistd:
 | 
			
		||||
        print "WEIRD: Could not locate the i386/x86 unistd.h header file,"
 | 
			
		||||
        print "maybe using a different set of kernel headers might help."
 | 
			
		||||
        sys.exit(1)
 | 
			
		||||
 | 
			
		||||
mips_unistd = find_arch_header(linux_root, "mips", "unistd.h")
 | 
			
		||||
if not mips_unistd:
 | 
			
		||||
    print "WEIRD: Could not locate the Mips unistd.h kernel header file,"
 | 
			
		||||
    print "maybe using a different set of kernel headers might help."
 | 
			
		||||
    sys.exit(1)
 | 
			
		||||
 | 
			
		||||
process_header( arm_unistd, arm_dict )
 | 
			
		||||
process_header( x86_unistd, x86_dict )
 | 
			
		||||
process_header( mips_unistd, mips_dict )
 | 
			
		||||
 | 
			
		||||
# now perform the comparison
 | 
			
		||||
errors = 0
 | 
			
		||||
 | 
			
		||||
def check_syscalls(archname, idname, arch_dict):
 | 
			
		||||
    errors = 0
 | 
			
		||||
    for sc in syscalls:
 | 
			
		||||
        sc_name = sc["name"]
 | 
			
		||||
        sc_id   = sc[idname]
 | 
			
		||||
        if sc_id == -1:
 | 
			
		||||
            sc_id = sc["common"]
 | 
			
		||||
        if sc_id >= 0:
 | 
			
		||||
            if not arch_dict.has_key(sc_name):
 | 
			
		||||
                print "error: %s syscall %s not defined, should be %d" % (archname, sc_name, sc_id)
 | 
			
		||||
                errors += 1
 | 
			
		||||
            elif arch_dict[sc_name] != sc_id:
 | 
			
		||||
                print "error: %s syscall %s should be %d instead of %d" % (archname, sc_name, arch_dict[sc_name], sc_id)
 | 
			
		||||
                errors += 1
 | 
			
		||||
    return errors
 | 
			
		||||
 | 
			
		||||
errors += check_syscalls("arm", "armid", arm_dict)
 | 
			
		||||
errors += check_syscalls("x86", "x86id", x86_dict)
 | 
			
		||||
errors += check_syscalls("mips", "mipsid", mips_dict)
 | 
			
		||||
 | 
			
		||||
if errors == 0:
 | 
			
		||||
    print "congratulations, everything's fine !!"
 | 
			
		||||
else:
 | 
			
		||||
    print "correct %d errors !!" % errors
 | 
			
		||||
@@ -3,6 +3,7 @@
 | 
			
		||||
"""Updates the tzdata file."""
 | 
			
		||||
 | 
			
		||||
import ftplib
 | 
			
		||||
import httplib
 | 
			
		||||
import os
 | 
			
		||||
import re
 | 
			
		||||
import subprocess
 | 
			
		||||
@@ -58,27 +59,57 @@ def WriteSetupFile():
 | 
			
		||||
  setup.close()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def Retrieve(ftp, filename):
 | 
			
		||||
  ftp.retrbinary('RETR %s' % filename, open(filename, 'wb').write)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def UpgradeTo(ftp, data_filename):
 | 
			
		||||
  """Downloads and repackages the given data from the given FTP server."""
 | 
			
		||||
 | 
			
		||||
  new_version = re.search('(tzdata.+)\\.tar\\.gz', data_filename).group(1)
 | 
			
		||||
 | 
			
		||||
  # Switch to a temporary directory.
 | 
			
		||||
def SwitchToNewTemporaryDirectory():
 | 
			
		||||
  tmp_dir = tempfile.mkdtemp('-tzdata')
 | 
			
		||||
  os.chdir(tmp_dir)
 | 
			
		||||
  print 'Created temporary directory "%s"...' % tmp_dir
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def FtpRetrieve(ftp, filename):
 | 
			
		||||
  ftp.retrbinary('RETR %s' % filename, open(filename, 'wb').write)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def FtpUpgrade(ftp, data_filename):
 | 
			
		||||
  """Downloads and repackages the given data from the given FTP server."""
 | 
			
		||||
  SwitchToNewTemporaryDirectory()
 | 
			
		||||
 | 
			
		||||
  print 'Downloading data...'
 | 
			
		||||
  Retrieve(ftp, data_filename)
 | 
			
		||||
  FtpRetrieve(ftp, data_filename)
 | 
			
		||||
 | 
			
		||||
  print 'Downloading signature...'
 | 
			
		||||
  signature_filename = '%s.asc' % data_filename
 | 
			
		||||
  Retrieve(ftp, signature_filename)
 | 
			
		||||
  FtpRetrieve(ftp, signature_filename)
 | 
			
		||||
 | 
			
		||||
  ExtractAndCompile(data_filename)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def HttpRetrieve(http, path, output_filename):
 | 
			
		||||
  http.request("GET", path)
 | 
			
		||||
  f = open(output_filename, 'wb')
 | 
			
		||||
  f.write(http.getresponse().read())
 | 
			
		||||
  f.close()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def HttpUpgrade(http, data_filename):
 | 
			
		||||
  """Downloads and repackages the given data from the given HTTP server."""
 | 
			
		||||
  SwitchToNewTemporaryDirectory()
 | 
			
		||||
 | 
			
		||||
  path = "/time-zones/repository/releases/%s" % data_filename
 | 
			
		||||
 | 
			
		||||
  print 'Downloading data...'
 | 
			
		||||
  HttpRetrieve(http, path, data_filename)
 | 
			
		||||
 | 
			
		||||
  print 'Downloading signature...'
 | 
			
		||||
  signature_filename = '%s.asc' % data_filename
 | 
			
		||||
  HttpRetrieve(http, "%s.asc" % path, signature_filename)
 | 
			
		||||
 | 
			
		||||
  ExtractAndCompile(data_filename)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def ExtractAndCompile(data_filename):
 | 
			
		||||
  new_version = re.search('(tzdata.+)\\.tar\\.gz', data_filename).group(1)
 | 
			
		||||
 | 
			
		||||
  signature_filename = '%s.asc' % data_filename
 | 
			
		||||
  print 'Verifying signature...'
 | 
			
		||||
  # If this fails for you, you probably need to import Paul Eggert's public key:
 | 
			
		||||
  # gpg --recv-keys ED97E90E62AA7E34
 | 
			
		||||
@@ -113,14 +144,29 @@ def UpgradeTo(ftp, data_filename):
 | 
			
		||||
# See http://www.iana.org/time-zones/ for more about the source of this data.
 | 
			
		||||
def main():
 | 
			
		||||
  print 'Looking for new tzdata...'
 | 
			
		||||
  ftp = ftplib.FTP('ftp.iana.org')
 | 
			
		||||
  ftp.login()
 | 
			
		||||
  ftp.cwd('tz/releases')
 | 
			
		||||
 | 
			
		||||
  tzdata_filenames = []
 | 
			
		||||
  for filename in ftp.nlst():
 | 
			
		||||
    if filename.startswith('tzdata20') and filename.endswith('.tar.gz'):
 | 
			
		||||
      tzdata_filenames.append(filename)
 | 
			
		||||
  tzdata_filenames.sort()
 | 
			
		||||
 | 
			
		||||
  # The FTP server lets you download intermediate releases, and also lets you
 | 
			
		||||
  # download the signatures for verification, so it's your best choice.
 | 
			
		||||
  use_ftp = True
 | 
			
		||||
 | 
			
		||||
  if use_ftp:
 | 
			
		||||
    ftp = ftplib.FTP('ftp.iana.org')
 | 
			
		||||
    ftp.login()
 | 
			
		||||
    ftp.cwd('tz/releases')
 | 
			
		||||
    for filename in ftp.nlst():
 | 
			
		||||
      if filename.startswith('tzdata20') and filename.endswith('.tar.gz'):
 | 
			
		||||
        tzdata_filenames.append(filename)
 | 
			
		||||
    tzdata_filenames.sort()
 | 
			
		||||
  else:
 | 
			
		||||
    http = httplib.HTTPConnection('www.iana.org')
 | 
			
		||||
    http.request("GET", "/time-zones")
 | 
			
		||||
    index_lines = http.getresponse().read().split('\n')
 | 
			
		||||
    for line in index_lines:
 | 
			
		||||
      m = re.compile('.*href="/time-zones/repository/releases/(tzdata20\d\d\c\.tar\.gz)".*').match(line)
 | 
			
		||||
      if m:
 | 
			
		||||
        tzdata_filenames.append(m.group(1))
 | 
			
		||||
 | 
			
		||||
  # If you're several releases behind, we'll walk you through the upgrades
 | 
			
		||||
  # one by one.
 | 
			
		||||
@@ -129,7 +175,10 @@ def main():
 | 
			
		||||
  for filename in tzdata_filenames:
 | 
			
		||||
    if filename > current_filename:
 | 
			
		||||
      print 'Found new tzdata: %s' % filename
 | 
			
		||||
      UpgradeTo(ftp, filename)
 | 
			
		||||
      if use_ftp:
 | 
			
		||||
        FtpUpgrade(ftp, filename)
 | 
			
		||||
      else:
 | 
			
		||||
        HttpUpgrade(http, filename)
 | 
			
		||||
      sys.exit(0)
 | 
			
		||||
 | 
			
		||||
  print 'You already have the latest tzdata (%s)!' % current_version
 | 
			
		||||
@@ -2276,14 +2276,18 @@ static int __bionic_open_tzdata_path(const char* path, const char* olson_id, int
 | 
			
		||||
    int32_t data_offset;
 | 
			
		||||
    int32_t zonetab_offset;
 | 
			
		||||
  } header;
 | 
			
		||||
  if (TEMP_FAILURE_RETRY(read(fd, &header, sizeof(header))) != sizeof(header)) {
 | 
			
		||||
    fprintf(stderr, "%s: could not read header: %s\n", __FUNCTION__, strerror(errno));
 | 
			
		||||
  memset(&header, 0, sizeof(header));
 | 
			
		||||
  ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd, &header, sizeof(header)));
 | 
			
		||||
  if (bytes_read != sizeof(header)) {
 | 
			
		||||
    fprintf(stderr, "%s: could not read header of \"%s\": %s\n",
 | 
			
		||||
            __FUNCTION__, path, (bytes_read == -1) ? strerror(errno) : "short read");
 | 
			
		||||
    close(fd);
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (strncmp(header.tzdata_version, "tzdata", 6) != 0 || header.tzdata_version[11] != 0) {
 | 
			
		||||
    fprintf(stderr, "%s: bad magic: %s\n", __FUNCTION__, header.tzdata_version);
 | 
			
		||||
    fprintf(stderr, "%s: bad magic in \"%s\": \"%.6s\"\n",
 | 
			
		||||
            __FUNCTION__, path, header.tzdata_version);
 | 
			
		||||
    close(fd);
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
@@ -2296,7 +2300,8 @@ static int __bionic_open_tzdata_path(const char* path, const char* olson_id, int
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  if (TEMP_FAILURE_RETRY(lseek(fd, ntohl(header.index_offset), SEEK_SET)) == -1) {
 | 
			
		||||
    fprintf(stderr, "%s: couldn't seek to index: %s\n", __FUNCTION__, strerror(errno));
 | 
			
		||||
    fprintf(stderr, "%s: couldn't seek to index in \"%s\": %s\n",
 | 
			
		||||
            __FUNCTION__, path, strerror(errno));
 | 
			
		||||
    close(fd);
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
@@ -2330,11 +2335,14 @@ static int __bionic_open_tzdata_path(const char* path, const char* olson_id, int
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (TEMP_FAILURE_RETRY(lseek(fd, specific_zone_offset, SEEK_SET)) == -1) {
 | 
			
		||||
    fprintf(stderr, "%s: could not seek to %ld: %s\n", __FUNCTION__, specific_zone_offset, strerror(errno));
 | 
			
		||||
    fprintf(stderr, "%s: could not seek to %ld in \"%s\": %s\n",
 | 
			
		||||
            __FUNCTION__, specific_zone_offset, path, strerror(errno));
 | 
			
		||||
    close(fd);
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // TODO: check that there's TZ_MAGIC at this offset, so we can fall back to the other file if not.
 | 
			
		||||
 | 
			
		||||
  return fd;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -17,4 +17,12 @@
 | 
			
		||||
#ifndef _BIONIC_FREEBSD_COMPAT_H_included
 | 
			
		||||
#define _BIONIC_FREEBSD_COMPAT_H_included
 | 
			
		||||
 | 
			
		||||
#define __USE_BSD
 | 
			
		||||
 | 
			
		||||
#define _close close
 | 
			
		||||
#define _fcntl fcntl
 | 
			
		||||
#define _open open
 | 
			
		||||
 | 
			
		||||
#define _sseek __sseek /* Needed as long as we have a mix of OpenBSD and FreeBSD stdio. */
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/*	$OpenBSD: clrerr.c,v 1.6 2005/08/08 08:05:36 espie Exp $ */
 | 
			
		||||
/*-
 | 
			
		||||
 * Copyright (c) 1990, 1993
 | 
			
		||||
 *	The Regents of the University of California.  All rights reserved.
 | 
			
		||||
@@ -14,7 +13,7 @@
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 * 4. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 *    may be used to endorse or promote products derived from this software
 | 
			
		||||
 *    without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
@@ -31,14 +30,32 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if defined(LIBC_SCCS) && !defined(lint)
 | 
			
		||||
static char sccsid[] = "@(#)clrerr.c	8.1 (Berkeley) 6/4/93";
 | 
			
		||||
#endif /* LIBC_SCCS and not lint */
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
__FBSDID("$FreeBSD$");
 | 
			
		||||
 | 
			
		||||
#include "namespace.h"
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include "local.h"
 | 
			
		||||
#undef	clearerr
 | 
			
		||||
#include "un-namespace.h"
 | 
			
		||||
#include "libc_private.h"
 | 
			
		||||
 | 
			
		||||
#undef clearerr
 | 
			
		||||
#undef clearerr_unlocked
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
clearerr(FILE *fp)
 | 
			
		||||
clearerr(fp)
 | 
			
		||||
	FILE *fp;
 | 
			
		||||
{
 | 
			
		||||
	FLOCKFILE(fp);
 | 
			
		||||
	__sclearerr(fp);
 | 
			
		||||
	FUNLOCKFILE(fp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
clearerr_unlocked(FILE *fp)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	__sclearerr(fp);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/*	$OpenBSD: fclose.c,v 1.6 2005/08/08 08:05:36 espie Exp $ */
 | 
			
		||||
/*-
 | 
			
		||||
 * Copyright (c) 1990, 1993
 | 
			
		||||
 *	The Regents of the University of California.  All rights reserved.
 | 
			
		||||
@@ -14,7 +13,7 @@
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 * 4. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 *    may be used to endorse or promote products derived from this software
 | 
			
		||||
 *    without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
@@ -31,9 +30,19 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if defined(LIBC_SCCS) && !defined(lint)
 | 
			
		||||
static char sccsid[] = "@(#)fclose.c	8.1 (Berkeley) 6/4/93";
 | 
			
		||||
#endif /* LIBC_SCCS and not lint */
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
__FBSDID("$FreeBSD$");
 | 
			
		||||
 | 
			
		||||
#include "namespace.h"
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include "un-namespace.h"
 | 
			
		||||
#include <spinlock.h>
 | 
			
		||||
#include "libc_private.h"
 | 
			
		||||
#include "local.h"
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
@@ -46,7 +55,6 @@ fclose(FILE *fp)
 | 
			
		||||
		return (EOF);
 | 
			
		||||
	}
 | 
			
		||||
	FLOCKFILE(fp);
 | 
			
		||||
	WCIO_FREE(fp);
 | 
			
		||||
	r = fp->_flags & __SWR ? __sflush(fp) : 0;
 | 
			
		||||
	if (fp->_close != NULL && (*fp->_close)(fp->_cookie) < 0)
 | 
			
		||||
		r = EOF;
 | 
			
		||||
@@ -56,8 +64,22 @@ fclose(FILE *fp)
 | 
			
		||||
		FREEUB(fp);
 | 
			
		||||
	if (HASLB(fp))
 | 
			
		||||
		FREELB(fp);
 | 
			
		||||
	fp->_file = -1;
 | 
			
		||||
	fp->_r = fp->_w = 0;	/* Mess up if reaccessed. */
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Lock the spinlock used to protect __sglue list walk in
 | 
			
		||||
	 * __sfp().  The __sfp() uses fp->_flags == 0 test as an
 | 
			
		||||
	 * indication of the unused FILE.
 | 
			
		||||
	 *
 | 
			
		||||
	 * Taking the lock prevents possible compiler or processor
 | 
			
		||||
	 * reordering of the writes performed before the final _flags
 | 
			
		||||
	 * cleanup, making sure that we are done with the FILE before
 | 
			
		||||
	 * it is considered available.
 | 
			
		||||
	 */
 | 
			
		||||
	STDIO_THREAD_LOCK();
 | 
			
		||||
	fp->_flags = 0;		/* Release this FILE for reuse. */
 | 
			
		||||
	STDIO_THREAD_UNLOCK();
 | 
			
		||||
	FUNLOCKFILE(fp);
 | 
			
		||||
	return (r);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/*	$OpenBSD: fdopen.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
 | 
			
		||||
/*-
 | 
			
		||||
 * Copyright (c) 1990, 1993
 | 
			
		||||
 *	The Regents of the University of California.  All rights reserved.
 | 
			
		||||
@@ -14,7 +13,7 @@
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 * 4. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 *    may be used to endorse or promote products derived from this software
 | 
			
		||||
 *    without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
@@ -31,24 +30,47 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if defined(LIBC_SCCS) && !defined(lint)
 | 
			
		||||
static char sccsid[] = "@(#)fdopen.c	8.1 (Berkeley) 6/4/93";
 | 
			
		||||
#endif /* LIBC_SCCS and not lint */
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
__FBSDID("$FreeBSD$");
 | 
			
		||||
 | 
			
		||||
#include "namespace.h"
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#include "un-namespace.h"
 | 
			
		||||
#include "local.h"
 | 
			
		||||
 | 
			
		||||
FILE *
 | 
			
		||||
fdopen(int fd, const char *mode)
 | 
			
		||||
fdopen(fd, mode)
 | 
			
		||||
	int fd;
 | 
			
		||||
	const char *mode;
 | 
			
		||||
{
 | 
			
		||||
	FILE *fp;
 | 
			
		||||
	int flags, oflags, fdflags, tmp;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * File descriptors are a full int, but _file is only a short.
 | 
			
		||||
	 * If we get a valid file descriptor that is greater than
 | 
			
		||||
	 * SHRT_MAX, then the fd will get sign-extended into an
 | 
			
		||||
	 * invalid file descriptor.  Handle this case by failing the
 | 
			
		||||
	 * open.
 | 
			
		||||
	 */
 | 
			
		||||
	if (fd > SHRT_MAX) {
 | 
			
		||||
		errno = EMFILE;
 | 
			
		||||
		return (NULL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((flags = __sflags(mode, &oflags)) == 0)
 | 
			
		||||
		return (NULL);
 | 
			
		||||
 | 
			
		||||
	/* Make sure the mode the user wants is a subset of the actual mode. */
 | 
			
		||||
	if ((fdflags = fcntl(fd, F_GETFL, 0)) < 0)
 | 
			
		||||
	if ((fdflags = _fcntl(fd, F_GETFL, 0)) < 0)
 | 
			
		||||
		return (NULL);
 | 
			
		||||
	tmp = fdflags & O_ACCMODE;
 | 
			
		||||
	if (tmp != O_RDWR && (tmp != (oflags & O_ACCMODE))) {
 | 
			
		||||
@@ -58,11 +80,17 @@ fdopen(int fd, const char *mode)
 | 
			
		||||
 | 
			
		||||
	if ((fp = __sfp()) == NULL)
 | 
			
		||||
		return (NULL);
 | 
			
		||||
 | 
			
		||||
	if ((oflags & O_CLOEXEC) && _fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
 | 
			
		||||
		fp->_flags = 0;
 | 
			
		||||
		return (NULL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fp->_flags = flags;
 | 
			
		||||
	/*
 | 
			
		||||
	 * If opened for appending, but underlying descriptor does not have
 | 
			
		||||
	 * O_APPEND bit set, assert __SAPP so that __swrite() will lseek to
 | 
			
		||||
	 * end before each write.
 | 
			
		||||
	 * O_APPEND bit set, assert __SAPP so that __swrite() caller
 | 
			
		||||
	 * will _sseek() to the end before write.
 | 
			
		||||
	 */
 | 
			
		||||
	if ((oflags & O_APPEND) && !(fdflags & O_APPEND))
 | 
			
		||||
		fp->_flags |= __SAPP;
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/*	$OpenBSD: feof.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
 | 
			
		||||
/*-
 | 
			
		||||
 * Copyright (c) 1990, 1993
 | 
			
		||||
 *	The Regents of the University of California.  All rights reserved.
 | 
			
		||||
@@ -14,7 +13,7 @@
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 * 4. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 *    may be used to endorse or promote products derived from this software
 | 
			
		||||
 *    without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
@@ -31,21 +30,34 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include "local.h"
 | 
			
		||||
#if defined(LIBC_SCCS) && !defined(lint)
 | 
			
		||||
static char sccsid[] = "@(#)feof.c	8.1 (Berkeley) 6/4/93";
 | 
			
		||||
#endif /* LIBC_SCCS and not lint */
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
__FBSDID("$FreeBSD$");
 | 
			
		||||
 | 
			
		||||
#include "namespace.h"
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include "un-namespace.h"
 | 
			
		||||
#include "libc_private.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * A subroutine version of the macro feof.
 | 
			
		||||
 */
 | 
			
		||||
#undef feof
 | 
			
		||||
#undef feof_unlocked
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
feof(FILE *fp)
 | 
			
		||||
{
 | 
			
		||||
	int ret;
 | 
			
		||||
	int	ret;
 | 
			
		||||
 | 
			
		||||
	FLOCKFILE(fp);
 | 
			
		||||
	ret = __sfeof(fp);
 | 
			
		||||
	ret= __sfeof(fp);
 | 
			
		||||
	FUNLOCKFILE(fp);
 | 
			
		||||
	return (ret);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
feof_unlocked(FILE *fp)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	return (__sfeof(fp));
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/*	$OpenBSD: ferror.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
 | 
			
		||||
/*-
 | 
			
		||||
 * Copyright (c) 1990, 1993
 | 
			
		||||
 *	The Regents of the University of California.  All rights reserved.
 | 
			
		||||
@@ -14,7 +13,7 @@
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 * 4. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 *    may be used to endorse or promote products derived from this software
 | 
			
		||||
 *    without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
@@ -31,15 +30,34 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#if defined(LIBC_SCCS) && !defined(lint)
 | 
			
		||||
static char sccsid[] = "@(#)ferror.c	8.1 (Berkeley) 6/4/93";
 | 
			
		||||
#endif /* LIBC_SCCS and not lint */
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
__FBSDID("$FreeBSD$");
 | 
			
		||||
 | 
			
		||||
#include "namespace.h"
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include "un-namespace.h"
 | 
			
		||||
#include "libc_private.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * A subroutine version of the macro ferror.
 | 
			
		||||
 */
 | 
			
		||||
#undef ferror
 | 
			
		||||
#undef ferror_unlocked
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
ferror(FILE *fp)
 | 
			
		||||
{
 | 
			
		||||
	int	ret;
 | 
			
		||||
 | 
			
		||||
	FLOCKFILE(fp);
 | 
			
		||||
	ret = __sferror(fp);
 | 
			
		||||
	FUNLOCKFILE(fp);
 | 
			
		||||
	return (ret);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
ferror_unlocked(FILE *fp)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	return (__sferror(fp));
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/*	$OpenBSD: fgetln.c,v 1.7 2005/08/08 08:05:36 espie Exp $ */
 | 
			
		||||
/*-
 | 
			
		||||
 * Copyright (c) 1990, 1993
 | 
			
		||||
 *	The Regents of the University of California.  All rights reserved.
 | 
			
		||||
@@ -14,7 +13,7 @@
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 * 4. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 *    may be used to endorse or promote products derived from this software
 | 
			
		||||
 *    without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
@@ -31,9 +30,18 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if defined(LIBC_SCCS) && !defined(lint)
 | 
			
		||||
static char sccsid[] = "@(#)fgetln.c	8.2 (Berkeley) 1/2/94";
 | 
			
		||||
#endif /* LIBC_SCCS and not lint */
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
__FBSDID("$FreeBSD$");
 | 
			
		||||
 | 
			
		||||
#include "namespace.h"
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "un-namespace.h"
 | 
			
		||||
#include "libc_private.h"
 | 
			
		||||
#include "local.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
@@ -43,7 +51,7 @@
 | 
			
		||||
 * so we add 1 here.
 | 
			
		||||
#endif
 | 
			
		||||
 */
 | 
			
		||||
static int
 | 
			
		||||
int
 | 
			
		||||
__slbexpand(FILE *fp, size_t newsize)
 | 
			
		||||
{
 | 
			
		||||
	void *p;
 | 
			
		||||
@@ -51,7 +59,7 @@ __slbexpand(FILE *fp, size_t newsize)
 | 
			
		||||
#ifdef notdef
 | 
			
		||||
	++newsize;
 | 
			
		||||
#endif
 | 
			
		||||
	if ((size_t)fp->_lb._size >= newsize)
 | 
			
		||||
	if (fp->_lb._size >= newsize)
 | 
			
		||||
		return (0);
 | 
			
		||||
	if ((p = realloc(fp->_lb._base, newsize)) == NULL)
 | 
			
		||||
		return (-1);
 | 
			
		||||
@@ -62,7 +70,7 @@ __slbexpand(FILE *fp, size_t newsize)
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Get an input line.  The returned pointer often (but not always)
 | 
			
		||||
 * points into a stdio buffer.  Fgetline does not alter the text of
 | 
			
		||||
 * points into a stdio buffer.  Fgetln does not alter the text of
 | 
			
		||||
 * the returned line (which is thus not a C string because it will
 | 
			
		||||
 * not necessarily end with '\0'), but does allow callers to modify
 | 
			
		||||
 * it if they wish.  Thus, we set __SMOD in case the caller does.
 | 
			
		||||
@@ -71,18 +79,22 @@ char *
 | 
			
		||||
fgetln(FILE *fp, size_t *lenp)
 | 
			
		||||
{
 | 
			
		||||
	unsigned char *p;
 | 
			
		||||
	char *ret;
 | 
			
		||||
	size_t len;
 | 
			
		||||
	size_t off;
 | 
			
		||||
 | 
			
		||||
	FLOCKFILE(fp);
 | 
			
		||||
 | 
			
		||||
	ORIENT(fp, -1);
 | 
			
		||||
	/* make sure there is input */
 | 
			
		||||
	if (fp->_r <= 0 && __srefill(fp))
 | 
			
		||||
		goto error;
 | 
			
		||||
	if (fp->_r <= 0 && __srefill(fp)) {
 | 
			
		||||
		*lenp = 0;
 | 
			
		||||
		FUNLOCKFILE(fp);
 | 
			
		||||
		return (NULL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* look for a newline in the input */
 | 
			
		||||
	if ((p = memchr((void *)fp->_p, '\n', fp->_r)) != NULL) {
 | 
			
		||||
	if ((p = memchr((void *)fp->_p, '\n', (size_t)fp->_r)) != NULL) {
 | 
			
		||||
		char *ret;
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		 * Found one.  Flag buffer as modified to keep fseek from
 | 
			
		||||
		 * `optimising' a backward seek, in case the user stomps on
 | 
			
		||||
@@ -103,7 +115,7 @@ fgetln(FILE *fp, size_t *lenp)
 | 
			
		||||
	 * As a bonus, though, we can leave off the __SMOD.
 | 
			
		||||
	 *
 | 
			
		||||
	 * OPTIMISTIC is length that we (optimistically) expect will
 | 
			
		||||
	 * accommodate the `rest' of the string, on each trip through the
 | 
			
		||||
	 * accomodate the `rest' of the string, on each trip through the
 | 
			
		||||
	 * loop below.
 | 
			
		||||
	 */
 | 
			
		||||
#define OPTIMISTIC 80
 | 
			
		||||
@@ -123,7 +135,7 @@ fgetln(FILE *fp, size_t *lenp)
 | 
			
		||||
		off = len;
 | 
			
		||||
		if (__srefill(fp))
 | 
			
		||||
			break;	/* EOF or error: return partial line */
 | 
			
		||||
		if ((p = memchr((void *)fp->_p, '\n', fp->_r)) == NULL)
 | 
			
		||||
		if ((p = memchr((void *)fp->_p, '\n', (size_t)fp->_r)) == NULL)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		/* got it: finish up the line (like code above) */
 | 
			
		||||
@@ -139,12 +151,11 @@ fgetln(FILE *fp, size_t *lenp)
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
	*lenp = len;
 | 
			
		||||
	ret = (char *)fp->_lb._base;
 | 
			
		||||
#ifdef notdef
 | 
			
		||||
	ret[len] = '\0';
 | 
			
		||||
	fp->_lb._base[len] = 0;
 | 
			
		||||
#endif
 | 
			
		||||
	FUNLOCKFILE(fp);
 | 
			
		||||
	return (ret);
 | 
			
		||||
	return ((char *)fp->_lb._base);
 | 
			
		||||
 | 
			
		||||
error:
 | 
			
		||||
	*lenp = 0;		/* ??? */
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/*	$OpenBSD: fgetpos.c,v 1.6 2005/08/08 08:05:36 espie Exp $ */
 | 
			
		||||
/*-
 | 
			
		||||
 * Copyright (c) 1990, 1993
 | 
			
		||||
 *	The Regents of the University of California.  All rights reserved.
 | 
			
		||||
@@ -14,7 +13,7 @@
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 * 4. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 *    may be used to endorse or promote products derived from this software
 | 
			
		||||
 *    without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
@@ -31,13 +30,22 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if defined(LIBC_SCCS) && !defined(lint)
 | 
			
		||||
static char sccsid[] = "@(#)fgetpos.c	8.1 (Berkeley) 6/4/93";
 | 
			
		||||
#endif /* LIBC_SCCS and not lint */
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
__FBSDID("$FreeBSD$");
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * fgetpos: like ftello.
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
fgetpos(FILE *fp, fpos_t *pos)
 | 
			
		||||
fgetpos(FILE * __restrict fp, fpos_t * __restrict pos)
 | 
			
		||||
{
 | 
			
		||||
	return((*pos = ftello(fp)) == (fpos_t)-1);
 | 
			
		||||
	/*
 | 
			
		||||
	 * ftello is thread-safe; no need to lock fp.
 | 
			
		||||
	 */
 | 
			
		||||
	if ((*pos = ftello(fp)) == (fpos_t)-1)
 | 
			
		||||
		return (-1);
 | 
			
		||||
	else
 | 
			
		||||
		return (0);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/*	$OpenBSD: fgets.c,v 1.10 2005/08/08 08:05:36 espie Exp $ */
 | 
			
		||||
/*-
 | 
			
		||||
 * Copyright (c) 1990, 1993
 | 
			
		||||
 *	The Regents of the University of California.  All rights reserved.
 | 
			
		||||
@@ -14,7 +13,7 @@
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 * 4. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 *    may be used to endorse or promote products derived from this software
 | 
			
		||||
 *    without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
@@ -31,18 +30,29 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if defined(LIBC_SCCS) && !defined(lint)
 | 
			
		||||
static char sccsid[] = "@(#)fgets.c	8.2 (Berkeley) 12/22/93";
 | 
			
		||||
#endif /* LIBC_SCCS and not lint */
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
__FBSDID("$FreeBSD$");
 | 
			
		||||
 | 
			
		||||
#include "namespace.h"
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "un-namespace.h"
 | 
			
		||||
#include "local.h"
 | 
			
		||||
#include "libc_private.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Read at most n-1 characters from the given file.
 | 
			
		||||
 * Stop when a newline has been read, or the count runs out.
 | 
			
		||||
 * Return first argument, or NULL if no characters were read.
 | 
			
		||||
 * Do not return NULL if n == 1.
 | 
			
		||||
 */
 | 
			
		||||
char *
 | 
			
		||||
fgets(char *buf, int n, FILE *fp)
 | 
			
		||||
fgets(buf, n, fp)
 | 
			
		||||
	char *buf;
 | 
			
		||||
	int n;
 | 
			
		||||
	FILE *fp;
 | 
			
		||||
{
 | 
			
		||||
	size_t len;
 | 
			
		||||
	char *s;
 | 
			
		||||
@@ -52,24 +62,24 @@ fgets(char *buf, int n, FILE *fp)
 | 
			
		||||
		return (NULL);
 | 
			
		||||
 | 
			
		||||
	FLOCKFILE(fp);
 | 
			
		||||
	_SET_ORIENTATION(fp, -1);
 | 
			
		||||
	ORIENT(fp, -1);
 | 
			
		||||
	s = buf;
 | 
			
		||||
	n--;			/* leave space for NUL */
 | 
			
		||||
	while (n != 0) {
 | 
			
		||||
		/*
 | 
			
		||||
		 * If the buffer is empty, refill it.
 | 
			
		||||
		 */
 | 
			
		||||
		if (fp->_r <= 0) {
 | 
			
		||||
		if ((len = fp->_r) <= 0) {
 | 
			
		||||
			if (__srefill(fp)) {
 | 
			
		||||
				/* EOF/error: stop with partial or no line */
 | 
			
		||||
				if (s == buf) {
 | 
			
		||||
					FUNLOCKFILE(fp);
 | 
			
		||||
					return (NULL);
 | 
			
		||||
                                }
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			len = fp->_r;
 | 
			
		||||
		}
 | 
			
		||||
		len = fp->_r;
 | 
			
		||||
		p = fp->_p;
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
@@ -78,7 +88,7 @@ fgets(char *buf, int n, FILE *fp)
 | 
			
		||||
		 * newline, and stop.  Otherwise, copy entire chunk
 | 
			
		||||
		 * and loop.
 | 
			
		||||
		 */
 | 
			
		||||
		if ((int)len > n)
 | 
			
		||||
		if (len > n)
 | 
			
		||||
			len = n;
 | 
			
		||||
		t = memchr((void *)p, '\n', len);
 | 
			
		||||
		if (t != NULL) {
 | 
			
		||||
@@ -86,7 +96,7 @@ fgets(char *buf, int n, FILE *fp)
 | 
			
		||||
			fp->_r -= len;
 | 
			
		||||
			fp->_p = t;
 | 
			
		||||
			(void)memcpy((void *)s, (void *)p, len);
 | 
			
		||||
			s[len] = '\0';
 | 
			
		||||
			s[len] = 0;
 | 
			
		||||
			FUNLOCKFILE(fp);
 | 
			
		||||
			return (buf);
 | 
			
		||||
		}
 | 
			
		||||
@@ -96,7 +106,7 @@ fgets(char *buf, int n, FILE *fp)
 | 
			
		||||
		s += len;
 | 
			
		||||
		n -= len;
 | 
			
		||||
	}
 | 
			
		||||
	*s = '\0';
 | 
			
		||||
	*s = 0;
 | 
			
		||||
	FUNLOCKFILE(fp);
 | 
			
		||||
	return (buf);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/*	$OpenBSD: fileno.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
 | 
			
		||||
/*-
 | 
			
		||||
 * Copyright (c) 1990, 1993
 | 
			
		||||
 *	The Regents of the University of California.  All rights reserved.
 | 
			
		||||
@@ -14,7 +13,7 @@
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 * 4. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 *    may be used to endorse or promote products derived from this software
 | 
			
		||||
 *    without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
@@ -31,21 +30,35 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include "local.h"
 | 
			
		||||
#if defined(LIBC_SCCS) && !defined(lint)
 | 
			
		||||
static char sccsid[] = "@(#)fileno.c	8.1 (Berkeley) 6/4/93";
 | 
			
		||||
#endif /* LIBC_SCCS and not lint */
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
__FBSDID("$FreeBSD$");
 | 
			
		||||
 | 
			
		||||
#include "namespace.h"
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include "un-namespace.h"
 | 
			
		||||
#include "libc_private.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * A subroutine version of the macro fileno.
 | 
			
		||||
 */
 | 
			
		||||
#undef fileno
 | 
			
		||||
#undef fileno_unlocked
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
fileno(FILE *fp)
 | 
			
		||||
{
 | 
			
		||||
	int ret;
 | 
			
		||||
	int fd;
 | 
			
		||||
 | 
			
		||||
	FLOCKFILE(fp);
 | 
			
		||||
	ret = __sfileno(fp);
 | 
			
		||||
	fd = __sfileno(fp);
 | 
			
		||||
	FUNLOCKFILE(fp);
 | 
			
		||||
	return (ret);
 | 
			
		||||
 | 
			
		||||
	return (fd);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
fileno_unlocked(FILE *fp)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	return (__sfileno(fp));
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/*	$OpenBSD: flags.c,v 1.6 2005/08/08 08:05:36 espie Exp $ */
 | 
			
		||||
/*-
 | 
			
		||||
 * Copyright (c) 1990, 1993
 | 
			
		||||
 *	The Regents of the University of California.  All rights reserved.
 | 
			
		||||
@@ -14,7 +13,7 @@
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 * 4. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 *    may be used to endorse or promote products derived from this software
 | 
			
		||||
 *    without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
@@ -31,19 +30,28 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if defined(LIBC_SCCS) && !defined(lint)
 | 
			
		||||
static char sccsid[] = "@(#)flags.c	8.1 (Berkeley) 6/4/93";
 | 
			
		||||
#endif /* LIBC_SCCS and not lint */
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
__FBSDID("$FreeBSD$");
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/file.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
 | 
			
		||||
#include "local.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Return the (stdio) flags for a given mode.  Store the flags
 | 
			
		||||
 * to be passed to an open() syscall through *optr.
 | 
			
		||||
 * to be passed to an _open() syscall through *optr.
 | 
			
		||||
 * Return 0 on error.
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
__sflags(const char *mode, int *optr)
 | 
			
		||||
__sflags(mode, optr)
 | 
			
		||||
	const char *mode;
 | 
			
		||||
	int *optr;
 | 
			
		||||
{
 | 
			
		||||
	int ret, m, o;
 | 
			
		||||
 | 
			
		||||
@@ -72,11 +80,35 @@ __sflags(const char *mode, int *optr)
 | 
			
		||||
		return (0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* [rwa]\+ or [rwa]b\+ means read and write */
 | 
			
		||||
	if (*mode == '+' || (*mode == 'b' && mode[1] == '+')) {
 | 
			
		||||
	/* 'b' (binary) is ignored */
 | 
			
		||||
	if (*mode == 'b')
 | 
			
		||||
		mode++;
 | 
			
		||||
 | 
			
		||||
	/* [rwa][b]\+ means read and write */
 | 
			
		||||
	if (*mode == '+') {
 | 
			
		||||
		mode++;
 | 
			
		||||
		ret = __SRW;
 | 
			
		||||
		m = O_RDWR;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* 'b' (binary) can appear here, too -- and is ignored again */
 | 
			
		||||
	if (*mode == 'b')
 | 
			
		||||
		mode++;
 | 
			
		||||
 | 
			
		||||
	/* 'x' means exclusive (fail if the file exists) */
 | 
			
		||||
	if (*mode == 'x') {
 | 
			
		||||
		mode++;
 | 
			
		||||
		if (m == O_RDONLY) {
 | 
			
		||||
			errno = EINVAL;
 | 
			
		||||
			return (0);
 | 
			
		||||
		}
 | 
			
		||||
		o |= O_EXCL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* set close-on-exec */
 | 
			
		||||
	if (*mode == 'e')
 | 
			
		||||
		o |= O_CLOEXEC;
 | 
			
		||||
 | 
			
		||||
	*optr = m | o;
 | 
			
		||||
	return (ret);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/*	$OpenBSD: fopen.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
 | 
			
		||||
/*-
 | 
			
		||||
 * Copyright (c) 1990, 1993
 | 
			
		||||
 *	The Regents of the University of California.  All rights reserved.
 | 
			
		||||
@@ -14,7 +13,7 @@
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 * 4. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 *    may be used to endorse or promote products derived from this software
 | 
			
		||||
 *    without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
@@ -31,18 +30,28 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define __USE_BSD
 | 
			
		||||
#if defined(LIBC_SCCS) && !defined(lint)
 | 
			
		||||
static char sccsid[] = "@(#)fopen.c	8.1 (Berkeley) 6/4/93";
 | 
			
		||||
#endif /* LIBC_SCCS and not lint */
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
__FBSDID("$FreeBSD$");
 | 
			
		||||
 | 
			
		||||
#include "namespace.h"
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#include "un-namespace.h"
 | 
			
		||||
 | 
			
		||||
#include "local.h"
 | 
			
		||||
#include <linux/stat.h>
 | 
			
		||||
 | 
			
		||||
FILE *
 | 
			
		||||
fopen(const char *file, const char *mode)
 | 
			
		||||
fopen(file, mode)
 | 
			
		||||
	const char * __restrict file;
 | 
			
		||||
	const char * __restrict mode;
 | 
			
		||||
{
 | 
			
		||||
	FILE *fp;
 | 
			
		||||
	int f;
 | 
			
		||||
@@ -52,10 +61,23 @@ fopen(const char *file, const char *mode)
 | 
			
		||||
		return (NULL);
 | 
			
		||||
	if ((fp = __sfp()) == NULL)
 | 
			
		||||
		return (NULL);
 | 
			
		||||
	if ((f = open(file, oflags, DEFFILEMODE)) < 0) {
 | 
			
		||||
	if ((f = _open(file, oflags, DEFFILEMODE)) < 0) {
 | 
			
		||||
		fp->_flags = 0;			/* release */
 | 
			
		||||
		return (NULL);
 | 
			
		||||
	}
 | 
			
		||||
	/*
 | 
			
		||||
	 * File descriptors are a full int, but _file is only a short.
 | 
			
		||||
	 * If we get a valid file descriptor that is greater than
 | 
			
		||||
	 * SHRT_MAX, then the fd will get sign-extended into an
 | 
			
		||||
	 * invalid file descriptor.  Handle this case by failing the
 | 
			
		||||
	 * open.
 | 
			
		||||
	 */
 | 
			
		||||
	if (f > SHRT_MAX) {
 | 
			
		||||
		fp->_flags = 0;			/* release */
 | 
			
		||||
		_close(f);
 | 
			
		||||
		errno = EMFILE;
 | 
			
		||||
		return (NULL);
 | 
			
		||||
	}
 | 
			
		||||
	fp->_file = f;
 | 
			
		||||
	fp->_flags = flags;
 | 
			
		||||
	fp->_cookie = fp;
 | 
			
		||||
@@ -63,7 +85,6 @@ fopen(const char *file, const char *mode)
 | 
			
		||||
	fp->_write = __swrite;
 | 
			
		||||
	fp->_seek = __sseek;
 | 
			
		||||
	fp->_close = __sclose;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * When opening in append mode, even though we use O_APPEND,
 | 
			
		||||
	 * we need to seek to the end so that ftell() gets the right
 | 
			
		||||
@@ -73,6 +94,6 @@ fopen(const char *file, const char *mode)
 | 
			
		||||
	 * fseek and ftell.)
 | 
			
		||||
	 */
 | 
			
		||||
	if (oflags & O_APPEND)
 | 
			
		||||
		(void) __sseek((void *)fp, (fpos_t)0, SEEK_END);
 | 
			
		||||
		(void)_sseek(fp, (fpos_t)0, SEEK_END);
 | 
			
		||||
	return (fp);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/*	$OpenBSD: fpurge.c,v 1.6 2005/08/08 08:05:36 espie Exp $ */
 | 
			
		||||
/*-
 | 
			
		||||
 * Copyright (c) 1990, 1993
 | 
			
		||||
 *	The Regents of the University of California.  All rights reserved.
 | 
			
		||||
@@ -14,7 +13,7 @@
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 * 4. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 *    may be used to endorse or promote products derived from this software
 | 
			
		||||
 *    without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
@@ -31,31 +30,41 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if defined(LIBC_SCCS) && !defined(lint)
 | 
			
		||||
static char sccsid[] = "@(#)fpurge.c	8.1 (Berkeley) 6/4/93";
 | 
			
		||||
#endif /* LIBC_SCCS and not lint */
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
__FBSDID("$FreeBSD$");
 | 
			
		||||
 | 
			
		||||
#include "namespace.h"
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include "un-namespace.h"
 | 
			
		||||
#include "local.h"
 | 
			
		||||
#include "libc_private.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * fpurge: like fflush, but without writing anything: leave the
 | 
			
		||||
 * given FILE's buffer empty.
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
fpurge(FILE *fp)
 | 
			
		||||
fpurge(fp)
 | 
			
		||||
	FILE *fp;
 | 
			
		||||
{
 | 
			
		||||
	int retval;
 | 
			
		||||
	FLOCKFILE(fp);
 | 
			
		||||
	if (!fp->_flags) {
 | 
			
		||||
		FUNLOCKFILE(fp);
 | 
			
		||||
		errno = EBADF;
 | 
			
		||||
		return(EOF);
 | 
			
		||||
		retval = EOF;
 | 
			
		||||
	} else {
 | 
			
		||||
		if (HASUB(fp))
 | 
			
		||||
			FREEUB(fp);
 | 
			
		||||
		fp->_p = fp->_bf._base;
 | 
			
		||||
		fp->_r = 0;
 | 
			
		||||
		fp->_w = fp->_flags & (__SLBF|__SNBF|__SRD) ? 0 : fp->_bf._size;
 | 
			
		||||
		retval = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (HASUB(fp))
 | 
			
		||||
		FREEUB(fp);
 | 
			
		||||
	WCIO_FREE(fp);
 | 
			
		||||
	fp->_p = fp->_bf._base;
 | 
			
		||||
	fp->_r = 0;
 | 
			
		||||
	fp->_w = fp->_flags & (__SLBF|__SNBF) ? 0 : fp->_bf._size;
 | 
			
		||||
	FUNLOCKFILE(fp);
 | 
			
		||||
	return (0);
 | 
			
		||||
	return (retval);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/*	$OpenBSD: fputs.c,v 1.7 2005/08/08 08:05:36 espie Exp $ */
 | 
			
		||||
/*-
 | 
			
		||||
 * Copyright (c) 1990, 1993
 | 
			
		||||
 *	The Regents of the University of California.  All rights reserved.
 | 
			
		||||
@@ -14,7 +13,7 @@
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 * 4. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 *    may be used to endorse or promote products derived from this software
 | 
			
		||||
 *    without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
@@ -31,28 +30,39 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if defined(LIBC_SCCS) && !defined(lint)
 | 
			
		||||
static char sccsid[] = "@(#)fputs.c	8.1 (Berkeley) 6/4/93";
 | 
			
		||||
#endif /* LIBC_SCCS and not lint */
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
__FBSDID("$FreeBSD$");
 | 
			
		||||
 | 
			
		||||
#include "namespace.h"
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "local.h"
 | 
			
		||||
#include "un-namespace.h"
 | 
			
		||||
#include "fvwrite.h"
 | 
			
		||||
#include "libc_private.h"
 | 
			
		||||
#include "local.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Write the given string to the given file.
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
fputs(const char *s, FILE *fp)
 | 
			
		||||
fputs(s, fp)
 | 
			
		||||
	const char * __restrict s;
 | 
			
		||||
	FILE * __restrict fp;
 | 
			
		||||
{
 | 
			
		||||
	int retval;
 | 
			
		||||
	struct __suio uio;
 | 
			
		||||
	struct __siov iov;
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	iov.iov_base = (void *)s;
 | 
			
		||||
	iov.iov_len = uio.uio_resid = strlen(s);
 | 
			
		||||
	uio.uio_iov = &iov;
 | 
			
		||||
	uio.uio_iovcnt = 1;
 | 
			
		||||
	FLOCKFILE(fp);
 | 
			
		||||
	_SET_ORIENTATION(fp, -1);
 | 
			
		||||
	ret = __sfvwrite(fp, &uio);
 | 
			
		||||
	ORIENT(fp, -1);
 | 
			
		||||
	retval = __sfvwrite(fp, &uio);
 | 
			
		||||
	FUNLOCKFILE(fp);
 | 
			
		||||
	return (ret);
 | 
			
		||||
	return (retval);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/*	$OpenBSD: fsetpos.c,v 1.6 2005/08/08 08:05:36 espie Exp $ */
 | 
			
		||||
/*-
 | 
			
		||||
 * Copyright (c) 1990, 1993
 | 
			
		||||
 *	The Regents of the University of California.  All rights reserved.
 | 
			
		||||
@@ -14,7 +13,7 @@
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 * 4. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 *    may be used to endorse or promote products derived from this software
 | 
			
		||||
 *    without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
@@ -31,13 +30,22 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if defined(LIBC_SCCS) && !defined(lint)
 | 
			
		||||
static char sccsid[] = "@(#)fsetpos.c	8.1 (Berkeley) 6/4/93";
 | 
			
		||||
#endif /* LIBC_SCCS and not lint */
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
__FBSDID("$FreeBSD$");
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * fsetpos: like fseeko.
 | 
			
		||||
 * fsetpos: like fseek.
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
fsetpos(FILE *iop, const fpos_t *pos)
 | 
			
		||||
fsetpos(iop, pos)
 | 
			
		||||
	FILE *iop;
 | 
			
		||||
	const fpos_t *pos;
 | 
			
		||||
{
 | 
			
		||||
	return (fseeko(iop, (off_t)*pos, SEEK_SET));
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/*	$OpenBSD: funopen.c,v 1.8 2005/08/08 08:05:36 espie Exp $ */
 | 
			
		||||
/*-
 | 
			
		||||
 * Copyright (c) 1990, 1993
 | 
			
		||||
 *	The Regents of the University of California.  All rights reserved.
 | 
			
		||||
@@ -14,7 +13,7 @@
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 * 4. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 *    may be used to endorse or promote products derived from this software
 | 
			
		||||
 *    without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
@@ -31,14 +30,23 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if defined(LIBC_SCCS) && !defined(lint)
 | 
			
		||||
static char sccsid[] = "@(#)funopen.c	8.1 (Berkeley) 6/4/93";
 | 
			
		||||
#endif /* LIBC_SCCS and not lint */
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
__FBSDID("$FreeBSD$");
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
 | 
			
		||||
#include "local.h"
 | 
			
		||||
 | 
			
		||||
FILE *
 | 
			
		||||
funopen(const void *cookie, int (*readfn)(void *, char *, int),
 | 
			
		||||
funopen(const void *cookie,
 | 
			
		||||
	int (*readfn)(void *, char *, int),
 | 
			
		||||
	int (*writefn)(void *, const char *, int),
 | 
			
		||||
	fpos_t (*seekfn)(void *, fpos_t, int), int (*closefn)(void *))
 | 
			
		||||
	fpos_t (*seekfn)(void *, fpos_t, int),
 | 
			
		||||
	int (*closefn)(void *))
 | 
			
		||||
{
 | 
			
		||||
	FILE *fp;
 | 
			
		||||
	int flags;
 | 
			
		||||
@@ -59,7 +67,7 @@ funopen(const void *cookie, int (*readfn)(void *, char *, int),
 | 
			
		||||
		return (NULL);
 | 
			
		||||
	fp->_flags = flags;
 | 
			
		||||
	fp->_file = -1;
 | 
			
		||||
	fp->_cookie = (void *)cookie;		/* SAFE: cookie not modified */
 | 
			
		||||
	fp->_cookie = (void *)cookie;
 | 
			
		||||
	fp->_read = readfn;
 | 
			
		||||
	fp->_write = writefn;
 | 
			
		||||
	fp->_seek = seekfn;
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/*	$OpenBSD: fwalk.c,v 1.7 2005/08/08 08:05:36 espie Exp $ */
 | 
			
		||||
/*-
 | 
			
		||||
 * Copyright (c) 1990, 1993
 | 
			
		||||
 *	The Regents of the University of California.  All rights reserved.
 | 
			
		||||
@@ -14,7 +13,7 @@
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 * 4. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 *    may be used to endorse or promote products derived from this software
 | 
			
		||||
 *    without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
@@ -31,23 +30,37 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#if defined(LIBC_SCCS) && !defined(lint)
 | 
			
		||||
static char sccsid[] = "@(#)fwalk.c	8.1 (Berkeley) 6/4/93";
 | 
			
		||||
#endif /* LIBC_SCCS and not lint */
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
__FBSDID("$FreeBSD$");
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include "local.h"
 | 
			
		||||
#include "glue.h"
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
_fwalk(int (*function)(FILE *))
 | 
			
		||||
_fwalk(function)
 | 
			
		||||
	int (*function)(FILE *);
 | 
			
		||||
{
 | 
			
		||||
	FILE *fp;
 | 
			
		||||
	int n, ret;
 | 
			
		||||
	struct glue *g;
 | 
			
		||||
 | 
			
		||||
	ret = 0;
 | 
			
		||||
	/*
 | 
			
		||||
	 * It should be safe to walk the list without locking it;
 | 
			
		||||
	 * new nodes are only added to the end and none are ever
 | 
			
		||||
	 * removed.
 | 
			
		||||
	 *
 | 
			
		||||
	 * Avoid locking this list while walking it or else you will
 | 
			
		||||
	 * introduce a potential deadlock in [at least] refill.c.
 | 
			
		||||
	 */
 | 
			
		||||
	for (g = &__sglue; g != NULL; g = g->next)
 | 
			
		||||
		for (fp = g->iobs, n = g->niobs; --n >= 0; fp++) {
 | 
			
		||||
		for (fp = g->iobs, n = g->niobs; --n >= 0; fp++)
 | 
			
		||||
			if ((fp->_flags != 0) && ((fp->_flags & __SIGN) == 0))
 | 
			
		||||
				ret |= (*function)(fp);
 | 
			
		||||
		}
 | 
			
		||||
	return (ret);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/*	$OpenBSD: fwrite.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
 | 
			
		||||
/*-
 | 
			
		||||
 * Copyright (c) 1990, 1993
 | 
			
		||||
 *	The Regents of the University of California.  All rights reserved.
 | 
			
		||||
@@ -14,7 +13,7 @@
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 * 4. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 *    may be used to endorse or promote products derived from this software
 | 
			
		||||
 *    without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
@@ -31,36 +30,70 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if defined(LIBC_SCCS) && !defined(lint)
 | 
			
		||||
static char sccsid[] = "@(#)fwrite.c	8.1 (Berkeley) 6/4/93";
 | 
			
		||||
#endif /* LIBC_SCCS and not lint */
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
__FBSDID("$FreeBSD$");
 | 
			
		||||
 | 
			
		||||
#include "namespace.h"
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include "un-namespace.h"
 | 
			
		||||
#include "local.h"
 | 
			
		||||
#include "fvwrite.h"
 | 
			
		||||
#include "libc_private.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Write `count' objects (each size `size') from memory to the given file.
 | 
			
		||||
 * Return the number of whole objects written.
 | 
			
		||||
 */
 | 
			
		||||
size_t
 | 
			
		||||
fwrite(const void *buf, size_t size, size_t count, FILE *fp)
 | 
			
		||||
fwrite(buf, size, count, fp)
 | 
			
		||||
	const void * __restrict buf;
 | 
			
		||||
	size_t size, count;
 | 
			
		||||
	FILE * __restrict fp;
 | 
			
		||||
{
 | 
			
		||||
	size_t n;
 | 
			
		||||
	struct __suio uio;
 | 
			
		||||
	struct __siov iov;
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * ANSI and SUSv2 require a return value of 0 if size or count are 0.
 | 
			
		||||
	 */
 | 
			
		||||
	if ((count == 0) || (size == 0))
 | 
			
		||||
		return (0);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Check for integer overflow.  As an optimization, first check that
 | 
			
		||||
	 * at least one of {count, size} is at least 2^16, since if both
 | 
			
		||||
	 * values are less than that, their product can't possible overflow
 | 
			
		||||
	 * (size_t is always at least 32 bits on FreeBSD).
 | 
			
		||||
	 */
 | 
			
		||||
	if (((count | size) > 0xFFFF) &&
 | 
			
		||||
	    (count > SIZE_MAX / size)) {
 | 
			
		||||
		errno = EINVAL;
 | 
			
		||||
		fp->_flags |= __SERR;
 | 
			
		||||
		return (0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	n = count * size;
 | 
			
		||||
 | 
			
		||||
	iov.iov_base = (void *)buf;
 | 
			
		||||
	uio.uio_resid = iov.iov_len = n = count * size;
 | 
			
		||||
	uio.uio_resid = iov.iov_len = n;
 | 
			
		||||
	uio.uio_iov = &iov;
 | 
			
		||||
	uio.uio_iovcnt = 1;
 | 
			
		||||
 | 
			
		||||
	FLOCKFILE(fp);
 | 
			
		||||
	ORIENT(fp, -1);
 | 
			
		||||
	/*
 | 
			
		||||
	 * The usual case is success (__sfvwrite returns 0);
 | 
			
		||||
	 * skip the divide if this happens, since divides are
 | 
			
		||||
	 * generally slow and since this occurs whenever size==0.
 | 
			
		||||
	 */
 | 
			
		||||
	FLOCKFILE(fp);
 | 
			
		||||
	ret = __sfvwrite(fp, &uio);
 | 
			
		||||
	if (__sfvwrite(fp, &uio) != 0)
 | 
			
		||||
	    count = (n - uio.uio_resid) / size;
 | 
			
		||||
	FUNLOCKFILE(fp);
 | 
			
		||||
	if (ret == 0)
 | 
			
		||||
		return (count);
 | 
			
		||||
	return ((n - uio.uio_resid) / size);
 | 
			
		||||
	return (count);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/*	$OpenBSD: getc.c,v 1.6 2005/08/08 08:05:36 espie Exp $ */
 | 
			
		||||
/*-
 | 
			
		||||
 * Copyright (c) 1990, 1993
 | 
			
		||||
 *	The Regents of the University of California.  All rights reserved.
 | 
			
		||||
@@ -14,7 +13,7 @@
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 * 4. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 *    may be used to endorse or promote products derived from this software
 | 
			
		||||
 *    without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
@@ -31,32 +30,36 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if defined(LIBC_SCCS) && !defined(lint)
 | 
			
		||||
static char sccsid[] = "@(#)getc.c	8.1 (Berkeley) 6/4/93";
 | 
			
		||||
#endif /* LIBC_SCCS and not lint */
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
__FBSDID("$FreeBSD$");
 | 
			
		||||
 | 
			
		||||
#include "namespace.h"
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include "un-namespace.h"
 | 
			
		||||
#include "libc_private.h"
 | 
			
		||||
#include "local.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * A subroutine version of the macro getc_unlocked.
 | 
			
		||||
 */
 | 
			
		||||
#undef getc_unlocked
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
getc_unlocked(FILE *fp)
 | 
			
		||||
{
 | 
			
		||||
	return (__sgetc(fp));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * A subroutine version of the macro getc.
 | 
			
		||||
 */
 | 
			
		||||
#undef getc
 | 
			
		||||
#undef getc_unlocked
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
getc(FILE *fp)
 | 
			
		||||
{
 | 
			
		||||
	int c;
 | 
			
		||||
 | 
			
		||||
	int retval;
 | 
			
		||||
	FLOCKFILE(fp);
 | 
			
		||||
	c = __sgetc(fp);
 | 
			
		||||
	/* Orientation set by __sgetc() when buffer is empty. */
 | 
			
		||||
	/* ORIENT(fp, -1); */
 | 
			
		||||
	retval = __sgetc(fp);
 | 
			
		||||
	FUNLOCKFILE(fp);
 | 
			
		||||
	return (c);
 | 
			
		||||
	return (retval);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
getc_unlocked(FILE *fp)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	return (__sgetc(fp));
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/*	$OpenBSD: getchar.c,v 1.7 2005/08/08 08:05:36 espie Exp $ */
 | 
			
		||||
/*-
 | 
			
		||||
 * Copyright (c) 1990, 1993
 | 
			
		||||
 *	The Regents of the University of California.  All rights reserved.
 | 
			
		||||
@@ -14,7 +13,7 @@
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 * 4. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 *    may be used to endorse or promote products derived from this software
 | 
			
		||||
 *    without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
@@ -31,28 +30,39 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * A subroutine version of the macro getchar_unlocked.
 | 
			
		||||
 */
 | 
			
		||||
#undef getchar_unlocked
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
getchar_unlocked(void)
 | 
			
		||||
{
 | 
			
		||||
	return (getc_unlocked(stdin));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if defined(LIBC_SCCS) && !defined(lint)
 | 
			
		||||
static char sccsid[] = "@(#)getchar.c	8.1 (Berkeley) 6/4/93";
 | 
			
		||||
#endif /* LIBC_SCCS and not lint */
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
__FBSDID("$FreeBSD$");
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * A subroutine version of the macro getchar.
 | 
			
		||||
 */
 | 
			
		||||
#include "namespace.h"
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include "un-namespace.h"
 | 
			
		||||
#include "local.h"
 | 
			
		||||
#include "libc_private.h"
 | 
			
		||||
 | 
			
		||||
#undef getchar
 | 
			
		||||
#undef getchar_unlocked
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
getchar(void)
 | 
			
		||||
getchar()
 | 
			
		||||
{
 | 
			
		||||
	return (getc(stdin));
 | 
			
		||||
	int retval;
 | 
			
		||||
	FLOCKFILE(stdin);
 | 
			
		||||
	/* Orientation set by __sgetc() when buffer is empty. */
 | 
			
		||||
	/* ORIENT(stdin, -1); */
 | 
			
		||||
	retval = __sgetc(stdin);
 | 
			
		||||
	FUNLOCKFILE(stdin);
 | 
			
		||||
	return (retval);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
getchar_unlocked(void)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	return (__sgetc(stdin));
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/*	$OpenBSD: putc.c,v 1.7 2005/08/08 08:05:36 espie Exp $ */
 | 
			
		||||
/*-
 | 
			
		||||
 * Copyright (c) 1990, 1993
 | 
			
		||||
 *	The Regents of the University of California.  All rights reserved.
 | 
			
		||||
@@ -14,7 +13,7 @@
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 * 4. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 *    may be used to endorse or promote products derived from this software
 | 
			
		||||
 *    without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
@@ -31,37 +30,38 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include "local.h"
 | 
			
		||||
#if defined(LIBC_SCCS) && !defined(lint)
 | 
			
		||||
static char sccsid[] = "@(#)putc.c	8.1 (Berkeley) 6/4/93";
 | 
			
		||||
#endif /* LIBC_SCCS and not lint */
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
__FBSDID("$FreeBSD$");
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * A subroutine version of the macro putc_unlocked.
 | 
			
		||||
 */
 | 
			
		||||
#include "namespace.h"
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include "un-namespace.h"
 | 
			
		||||
#include "local.h"
 | 
			
		||||
#include "libc_private.h"
 | 
			
		||||
 | 
			
		||||
#undef putc
 | 
			
		||||
#undef putc_unlocked
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
putc_unlocked(int c, FILE *fp)
 | 
			
		||||
putc(c, fp)
 | 
			
		||||
	int c;
 | 
			
		||||
	FILE *fp;
 | 
			
		||||
{
 | 
			
		||||
	if (cantwrite(fp)) {
 | 
			
		||||
		errno = EBADF;
 | 
			
		||||
		return (EOF);
 | 
			
		||||
	}
 | 
			
		||||
	return (__sputc(c, fp));
 | 
			
		||||
	int retval;
 | 
			
		||||
	FLOCKFILE(fp);
 | 
			
		||||
	/* Orientation set by __sputc() when buffer is full. */
 | 
			
		||||
	/* ORIENT(fp, -1); */
 | 
			
		||||
	retval = __sputc(c, fp);
 | 
			
		||||
	FUNLOCKFILE(fp);
 | 
			
		||||
	return (retval);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * A subroutine version of the macro putc.
 | 
			
		||||
 */
 | 
			
		||||
#undef putc
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
putc(int c, FILE *fp)
 | 
			
		||||
putc_unlocked(int ch, FILE *fp)
 | 
			
		||||
{
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	FLOCKFILE(fp);
 | 
			
		||||
	ret = putc_unlocked(c, fp);
 | 
			
		||||
	FUNLOCKFILE(fp);
 | 
			
		||||
	return (ret);
 | 
			
		||||
	return (__sputc(ch, fp));
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/*	$OpenBSD: putchar.c,v 1.7 2005/08/08 08:05:36 espie Exp $ */
 | 
			
		||||
/*-
 | 
			
		||||
 * Copyright (c) 1990, 1993
 | 
			
		||||
 *	The Regents of the University of California.  All rights reserved.
 | 
			
		||||
@@ -14,7 +13,7 @@
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 * 4. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 *    may be used to endorse or promote products derived from this software
 | 
			
		||||
 *    without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
@@ -31,29 +30,42 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if defined(LIBC_SCCS) && !defined(lint)
 | 
			
		||||
static char sccsid[] = "@(#)putchar.c	8.1 (Berkeley) 6/4/93";
 | 
			
		||||
#endif /* LIBC_SCCS and not lint */
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
__FBSDID("$FreeBSD$");
 | 
			
		||||
 | 
			
		||||
#include "namespace.h"
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
#undef putchar_unlocked
 | 
			
		||||
/*
 | 
			
		||||
 * A subrouting version of the macro putchar_unlocked
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
putchar_unlocked(int c)
 | 
			
		||||
{
 | 
			
		||||
	FILE *so = stdout;
 | 
			
		||||
 | 
			
		||||
	return (putc_unlocked(c, so));
 | 
			
		||||
}
 | 
			
		||||
#include "un-namespace.h"
 | 
			
		||||
#include "local.h"
 | 
			
		||||
#include "libc_private.h"
 | 
			
		||||
 | 
			
		||||
#undef putchar
 | 
			
		||||
#undef putchar_unlocked
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * A subroutine version of the macro putchar
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
putchar(int c)
 | 
			
		||||
putchar(c)
 | 
			
		||||
	int c;
 | 
			
		||||
{
 | 
			
		||||
	int retval;
 | 
			
		||||
	FILE *so = stdout;
 | 
			
		||||
 | 
			
		||||
	return (putc(c, so));
 | 
			
		||||
	FLOCKFILE(so);
 | 
			
		||||
	/* Orientation set by __sputc() when buffer is full. */
 | 
			
		||||
	/* ORIENT(so, -1); */
 | 
			
		||||
	retval = __sputc(c, so);
 | 
			
		||||
	FUNLOCKFILE(so);
 | 
			
		||||
	return (retval);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
putchar_unlocked(int ch)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	return (__sputc(ch, stdout));
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/*	$OpenBSD: puts.c,v 1.7 2005/08/08 08:05:36 espie Exp $ */
 | 
			
		||||
/*-
 | 
			
		||||
 * Copyright (c) 1990, 1993
 | 
			
		||||
 *	The Regents of the University of California.  All rights reserved.
 | 
			
		||||
@@ -14,7 +13,7 @@
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 * 4. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 *    may be used to endorse or promote products derived from this software
 | 
			
		||||
 *    without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
@@ -31,21 +30,31 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if defined(LIBC_SCCS) && !defined(lint)
 | 
			
		||||
static char sccsid[] = "@(#)puts.c	8.1 (Berkeley) 6/4/93";
 | 
			
		||||
#endif /* LIBC_SCCS and not lint */
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
__FBSDID("$FreeBSD$");
 | 
			
		||||
 | 
			
		||||
#include "namespace.h"
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "local.h"
 | 
			
		||||
#include "un-namespace.h"
 | 
			
		||||
#include "fvwrite.h"
 | 
			
		||||
#include "libc_private.h"
 | 
			
		||||
#include "local.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Write the given string to stdout, appending a newline.
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
puts(const char *s)
 | 
			
		||||
puts(s)
 | 
			
		||||
	char const *s;
 | 
			
		||||
{
 | 
			
		||||
	int retval;
 | 
			
		||||
	size_t c = strlen(s);
 | 
			
		||||
	struct __suio uio;
 | 
			
		||||
	struct __siov iov[2];
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	iov[0].iov_base = (void *)s;
 | 
			
		||||
	iov[0].iov_len = c;
 | 
			
		||||
@@ -55,7 +64,8 @@ puts(const char *s)
 | 
			
		||||
	uio.uio_iov = &iov[0];
 | 
			
		||||
	uio.uio_iovcnt = 2;
 | 
			
		||||
	FLOCKFILE(stdout);
 | 
			
		||||
	ret = __sfvwrite(stdout, &uio);
 | 
			
		||||
	ORIENT(stdout, -1);
 | 
			
		||||
	retval = __sfvwrite(stdout, &uio) ? EOF : '\n';
 | 
			
		||||
	FUNLOCKFILE(stdout);
 | 
			
		||||
	return (ret ? EOF : '\n');
 | 
			
		||||
	return (retval);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/*	$OpenBSD: putw.c,v 1.6 2005/08/08 08:05:36 espie Exp $ */
 | 
			
		||||
/*-
 | 
			
		||||
 * Copyright (c) 1990, 1993
 | 
			
		||||
 *	The Regents of the University of California.  All rights reserved.
 | 
			
		||||
@@ -14,7 +13,7 @@
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 * 4. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 *    may be used to endorse or promote products derived from this software
 | 
			
		||||
 *    without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
@@ -31,12 +30,24 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if defined(LIBC_SCCS) && !defined(lint)
 | 
			
		||||
static char sccsid[] = "@(#)putw.c	8.1 (Berkeley) 6/4/93";
 | 
			
		||||
#endif /* LIBC_SCCS and not lint */
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
__FBSDID("$FreeBSD$");
 | 
			
		||||
 | 
			
		||||
#include "namespace.h"
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include "un-namespace.h"
 | 
			
		||||
#include "fvwrite.h"
 | 
			
		||||
#include "libc_private.h"
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
putw(int w, FILE *fp)
 | 
			
		||||
putw(w, fp)
 | 
			
		||||
	int w;
 | 
			
		||||
	FILE *fp;
 | 
			
		||||
{
 | 
			
		||||
	int retval;
 | 
			
		||||
	struct __suio uio;
 | 
			
		||||
	struct __siov iov;
 | 
			
		||||
 | 
			
		||||
@@ -44,5 +55,8 @@ putw(int w, FILE *fp)
 | 
			
		||||
	iov.iov_len = uio.uio_resid = sizeof(w);
 | 
			
		||||
	uio.uio_iov = &iov;
 | 
			
		||||
	uio.uio_iovcnt = 1;
 | 
			
		||||
	return (__sfvwrite(fp, &uio));
 | 
			
		||||
	FLOCKFILE(fp);
 | 
			
		||||
	retval = __sfvwrite(fp, &uio);
 | 
			
		||||
	FUNLOCKFILE(fp);
 | 
			
		||||
	return (retval);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,5 +1,3 @@
 | 
			
		||||
/*	$OpenBSD: remove.c,v 1.7 2005/08/08 08:05:36 espie Exp $	*/
 | 
			
		||||
 | 
			
		||||
/*-
 | 
			
		||||
 * Copyright (c) 1990, 1993
 | 
			
		||||
 *	The Regents of the University of California.  All rights reserved.
 | 
			
		||||
@@ -15,7 +13,7 @@
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 * 4. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 *    may be used to endorse or promote products derived from this software
 | 
			
		||||
 *    without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
@@ -32,18 +30,26 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#if defined(LIBC_SCCS) && !defined(lint)
 | 
			
		||||
static char sccsid[] = "@(#)remove.c	8.1 (Berkeley) 6/4/93";
 | 
			
		||||
#endif /* LIBC_SCCS and not lint */
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
__FBSDID("$FreeBSD$");
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
remove(const char *file)
 | 
			
		||||
remove(file)
 | 
			
		||||
	const char *file;
 | 
			
		||||
{
 | 
			
		||||
	struct stat st;
 | 
			
		||||
	struct stat sb;
 | 
			
		||||
 | 
			
		||||
	if (lstat(file, &st) < 0)
 | 
			
		||||
	if (lstat(file, &sb) < 0)
 | 
			
		||||
		return (-1);
 | 
			
		||||
	if (S_ISDIR(st.st_mode))
 | 
			
		||||
	if (S_ISDIR(sb.st_mode))
 | 
			
		||||
		return (rmdir(file));
 | 
			
		||||
	return (unlink(file));
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/*	$OpenBSD: rget.c,v 1.7 2005/08/08 08:05:36 espie Exp $ */
 | 
			
		||||
/*-
 | 
			
		||||
 * Copyright (c) 1990, 1993
 | 
			
		||||
 *	The Regents of the University of California.  All rights reserved.
 | 
			
		||||
@@ -14,7 +13,7 @@
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 * 4. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 *    may be used to endorse or promote products derived from this software
 | 
			
		||||
 *    without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
@@ -31,6 +30,12 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if defined(LIBC_SCCS) && !defined(lint)
 | 
			
		||||
static char sccsid[] = "@(#)rget.c	8.1 (Berkeley) 6/4/93";
 | 
			
		||||
#endif /* LIBC_SCCS and not lint */
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
__FBSDID("$FreeBSD$");
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include "local.h"
 | 
			
		||||
 | 
			
		||||
@@ -42,7 +47,6 @@
 | 
			
		||||
int
 | 
			
		||||
__srget(FILE *fp)
 | 
			
		||||
{
 | 
			
		||||
	_SET_ORIENTATION(fp, -1);
 | 
			
		||||
	if (__srefill(fp) == 0) {
 | 
			
		||||
		fp->_r--;
 | 
			
		||||
		return (*fp->_p++);
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/*	$OpenBSD: setbuf.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
 | 
			
		||||
/*-
 | 
			
		||||
 * Copyright (c) 1990, 1993
 | 
			
		||||
 *	The Regents of the University of California.  All rights reserved.
 | 
			
		||||
@@ -14,7 +13,7 @@
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 * 4. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 *    may be used to endorse or promote products derived from this software
 | 
			
		||||
 *    without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
@@ -31,11 +30,17 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if defined(LIBC_SCCS) && !defined(lint)
 | 
			
		||||
static char sccsid[] = "@(#)setbuf.c	8.1 (Berkeley) 6/4/93";
 | 
			
		||||
#endif /* LIBC_SCCS and not lint */
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
__FBSDID("$FreeBSD$");
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include "local.h"
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
setbuf(FILE *fp, char *buf)
 | 
			
		||||
setbuf(FILE * __restrict fp, char * __restrict buf)
 | 
			
		||||
{
 | 
			
		||||
	(void) setvbuf(fp, buf, buf ? _IOFBF : _IONBF, BUFSIZ);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/*	$OpenBSD: setbuffer.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
 | 
			
		||||
/*-
 | 
			
		||||
 * Copyright (c) 1990, 1993
 | 
			
		||||
 *	The Regents of the University of California.  All rights reserved.
 | 
			
		||||
@@ -14,7 +13,7 @@
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 * 4. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 *    may be used to endorse or promote products derived from this software
 | 
			
		||||
 *    without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
@@ -31,20 +30,30 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if defined(LIBC_SCCS) && !defined(lint)
 | 
			
		||||
static char sccsid[] = "@(#)setbuffer.c	8.1 (Berkeley) 6/4/93";
 | 
			
		||||
#endif /* LIBC_SCCS and not lint */
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
__FBSDID("$FreeBSD$");
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
setbuffer(FILE *fp, char *buf, int size)
 | 
			
		||||
setbuffer(fp, buf, size)
 | 
			
		||||
	FILE *fp;
 | 
			
		||||
	char *buf;
 | 
			
		||||
	int size;
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	(void)setvbuf(fp, buf, buf ? _IOFBF : _IONBF, size);
 | 
			
		||||
	(void)setvbuf(fp, buf, buf ? _IOFBF : _IONBF, (size_t)size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * set line buffering
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
setlinebuf(FILE *fp)
 | 
			
		||||
setlinebuf(fp)
 | 
			
		||||
	FILE *fp;
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	return (setvbuf(fp, (char *)NULL, _IOLBF, (size_t)0));
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/*	$OpenBSD: tempnam.c,v 1.14 2005/08/08 08:05:36 espie Exp $ */
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 1988, 1993
 | 
			
		||||
 *	The Regents of the University of California.  All rights reserved.
 | 
			
		||||
@@ -11,7 +10,7 @@
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 * 4. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 *    may be used to endorse or promote products derived from this software
 | 
			
		||||
 *    without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
@@ -28,6 +27,12 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if defined(LIBC_SCCS) && !defined(lint)
 | 
			
		||||
static char sccsid[] = "@(#)tempnam.c	8.1 (Berkeley) 6/4/93";
 | 
			
		||||
#endif /* LIBC_SCCS and not lint */
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
__FBSDID("$FreeBSD$");
 | 
			
		||||
 | 
			
		||||
#include <sys/param.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
@@ -42,7 +47,8 @@ __warn_references(tempnam,
 | 
			
		||||
extern char *_mktemp(char *);
 | 
			
		||||
 | 
			
		||||
char *
 | 
			
		||||
tempnam(const char *dir, const char *pfx)
 | 
			
		||||
tempnam(dir, pfx)
 | 
			
		||||
	const char *dir, *pfx;
 | 
			
		||||
{
 | 
			
		||||
	int sverrno;
 | 
			
		||||
	char *f, *name;
 | 
			
		||||
@@ -54,26 +60,26 @@ tempnam(const char *dir, const char *pfx)
 | 
			
		||||
		pfx = "tmp.";
 | 
			
		||||
 | 
			
		||||
	if (issetugid() == 0 && (f = getenv("TMPDIR"))) {
 | 
			
		||||
		(void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXXXXXX", f,
 | 
			
		||||
		(void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXX", f,
 | 
			
		||||
		    *(f + strlen(f) - 1) == '/'? "": "/", pfx);
 | 
			
		||||
		if ((f = _mktemp(name)))
 | 
			
		||||
			return(f);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((f = (char *)dir)) {
 | 
			
		||||
		(void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXXXXXX", f,
 | 
			
		||||
		(void)snprintf(name, MAXPATHLEN, "%s%s%sXXXXXX", f,
 | 
			
		||||
		    *(f + strlen(f) - 1) == '/'? "": "/", pfx);
 | 
			
		||||
		if ((f = _mktemp(name)))
 | 
			
		||||
			return(f);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	f = P_tmpdir;
 | 
			
		||||
	(void)snprintf(name, MAXPATHLEN, "%s%sXXXXXXXXX", f, pfx);
 | 
			
		||||
	(void)snprintf(name, MAXPATHLEN, "%s%sXXXXXX", f, pfx);
 | 
			
		||||
	if ((f = _mktemp(name)))
 | 
			
		||||
		return(f);
 | 
			
		||||
 | 
			
		||||
	f = _PATH_TMP;
 | 
			
		||||
	(void)snprintf(name, MAXPATHLEN, "%s%sXXXXXXXXX", f, pfx);
 | 
			
		||||
	(void)snprintf(name, MAXPATHLEN, "%s%sXXXXXX", f, pfx);
 | 
			
		||||
	if ((f = _mktemp(name)))
 | 
			
		||||
		return(f);
 | 
			
		||||
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/*	$OpenBSD: tmpnam.c,v 1.10 2005/08/08 08:05:36 espie Exp $ */
 | 
			
		||||
/*-
 | 
			
		||||
 * Copyright (c) 1990, 1993, 1994
 | 
			
		||||
 *	The Regents of the University of California.  All rights reserved.
 | 
			
		||||
@@ -14,7 +13,7 @@
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 * 4. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 *    may be used to endorse or promote products derived from this software
 | 
			
		||||
 *    without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
@@ -31,6 +30,12 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if defined(LIBC_SCCS) && !defined(lint)
 | 
			
		||||
static char sccsid[] = "@(#)tmpnam.c	8.3 (Berkeley) 3/28/94";
 | 
			
		||||
#endif /* LIBC_SCCS and not lint */
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
__FBSDID("$FreeBSD$");
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
@@ -42,14 +47,15 @@ __warn_references(tmpnam,
 | 
			
		||||
extern char *_mktemp(char *);
 | 
			
		||||
 | 
			
		||||
char *
 | 
			
		||||
tmpnam(char *s)
 | 
			
		||||
tmpnam(s)
 | 
			
		||||
	char *s;
 | 
			
		||||
{
 | 
			
		||||
	static u_long tmpcount;
 | 
			
		||||
	static char buf[L_tmpnam];
 | 
			
		||||
 | 
			
		||||
	if (s == NULL)
 | 
			
		||||
		s = buf;
 | 
			
		||||
	(void)snprintf(s, L_tmpnam, "%stmp.%lu.XXXXXXXXX", P_tmpdir, tmpcount);
 | 
			
		||||
	(void)snprintf(s, L_tmpnam, "%stmp.%lu.XXXXXX", P_tmpdir, tmpcount);
 | 
			
		||||
	++tmpcount;
 | 
			
		||||
	return (_mktemp(s));
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/*	$OpenBSD: wsetup.c,v 1.7 2005/08/08 08:05:36 espie Exp $ */
 | 
			
		||||
/*-
 | 
			
		||||
 * Copyright (c) 1990, 1993
 | 
			
		||||
 *	The Regents of the University of California.  All rights reserved.
 | 
			
		||||
@@ -14,7 +13,7 @@
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 * 4. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 *    may be used to endorse or promote products derived from this software
 | 
			
		||||
 *    without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
@@ -31,6 +30,13 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if defined(LIBC_SCCS) && !defined(lint)
 | 
			
		||||
static char sccsid[] = "@(#)wsetup.c	8.1 (Berkeley) 6/4/93";
 | 
			
		||||
#endif /* LIBC_SCCS and not lint */
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
__FBSDID("$FreeBSD$");
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include "local.h"
 | 
			
		||||
@@ -38,10 +44,11 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Various output routines call wsetup to be sure it is safe to write,
 | 
			
		||||
 * because either _flags does not include __SWR, or _buf is NULL.
 | 
			
		||||
 * _wsetup returns 0 if OK to write, nonzero otherwise.
 | 
			
		||||
 * _wsetup returns 0 if OK to write; otherwise, it returns EOF and sets errno.
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
__swsetup(FILE *fp)
 | 
			
		||||
__swsetup(fp)
 | 
			
		||||
	FILE *fp;
 | 
			
		||||
{
 | 
			
		||||
	/* make sure stdio is set up */
 | 
			
		||||
	if (!__sdidinit)
 | 
			
		||||
@@ -51,8 +58,11 @@ __swsetup(FILE *fp)
 | 
			
		||||
	 * If we are not writing, we had better be reading and writing.
 | 
			
		||||
	 */
 | 
			
		||||
	if ((fp->_flags & __SWR) == 0) {
 | 
			
		||||
		if ((fp->_flags & __SRW) == 0)
 | 
			
		||||
		if ((fp->_flags & __SRW) == 0) {
 | 
			
		||||
			errno = EBADF;
 | 
			
		||||
			fp->_flags |= __SERR;
 | 
			
		||||
			return (EOF);
 | 
			
		||||
		}
 | 
			
		||||
		if (fp->_flags & __SRD) {
 | 
			
		||||
			/* clobber any ungetc data */
 | 
			
		||||
			if (HASUB(fp))
 | 
			
		||||
@@ -67,11 +77,8 @@ __swsetup(FILE *fp)
 | 
			
		||||
	/*
 | 
			
		||||
	 * Make a buffer if necessary, then set _w.
 | 
			
		||||
	 */
 | 
			
		||||
	if (fp->_bf._base == NULL) {
 | 
			
		||||
		if ((fp->_flags & (__SSTR | __SALC)) == __SSTR)
 | 
			
		||||
			return (EOF);
 | 
			
		||||
	if (fp->_bf._base == NULL)
 | 
			
		||||
		__smakebuf(fp);
 | 
			
		||||
	}
 | 
			
		||||
	if (fp->_flags & __SLBF) {
 | 
			
		||||
		/*
 | 
			
		||||
		 * It is line buffered, so make _lbfsize be -_bufsize
 | 
			
		||||
@@ -1,4 +1,3 @@
 | 
			
		||||
/*	$OpenBSD: qsort.c,v 1.10 2005/08/08 08:05:37 espie Exp $ */
 | 
			
		||||
/*-
 | 
			
		||||
 * Copyright (c) 1992, 1993
 | 
			
		||||
 *	The Regents of the University of California.  All rights reserved.
 | 
			
		||||
@@ -11,7 +10,7 @@
 | 
			
		||||
 * 2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *    notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *    documentation and/or other materials provided with the distribution.
 | 
			
		||||
 * 3. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 * 4. Neither the name of the University nor the names of its contributors
 | 
			
		||||
 *    may be used to endorse or promote products derived from this software
 | 
			
		||||
 *    without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
@@ -28,23 +27,33 @@
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#if defined(LIBC_SCCS) && !defined(lint)
 | 
			
		||||
static char sccsid[] = "@(#)qsort.c	8.1 (Berkeley) 6/4/93";
 | 
			
		||||
#endif /* LIBC_SCCS and not lint */
 | 
			
		||||
#include <sys/cdefs.h>
 | 
			
		||||
__FBSDID("$FreeBSD$");
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
static __inline char	*med3(char *, char *, char *, int (*)(const void *, const void *));
 | 
			
		||||
static __inline void	 swapfunc(char *, char *, int, int);
 | 
			
		||||
#ifdef I_AM_QSORT_R
 | 
			
		||||
typedef int		 cmp_t(void *, const void *, const void *);
 | 
			
		||||
#else
 | 
			
		||||
typedef int		 cmp_t(const void *, const void *);
 | 
			
		||||
#endif
 | 
			
		||||
static inline char	*med3(char *, char *, char *, cmp_t *, void *);
 | 
			
		||||
static inline void	 swapfunc(char *, char *, int, int);
 | 
			
		||||
 | 
			
		||||
#define min(a, b)	(a) < (b) ? a : b
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
 | 
			
		||||
 */
 | 
			
		||||
#define swapcode(TYPE, parmi, parmj, n) {		\
 | 
			
		||||
	long i = (n) / sizeof (TYPE);			\
 | 
			
		||||
	TYPE *pi = (TYPE *) (parmi);			\
 | 
			
		||||
	TYPE *pj = (TYPE *) (parmj);			\
 | 
			
		||||
	do {						\
 | 
			
		||||
		TYPE	t = *pi;			\
 | 
			
		||||
#define swapcode(TYPE, parmi, parmj, n) { 		\
 | 
			
		||||
	long i = (n) / sizeof (TYPE); 			\
 | 
			
		||||
	TYPE *pi = (TYPE *) (parmi); 		\
 | 
			
		||||
	TYPE *pj = (TYPE *) (parmj); 		\
 | 
			
		||||
	do { 						\
 | 
			
		||||
		TYPE	t = *pi;		\
 | 
			
		||||
		*pi++ = *pj;				\
 | 
			
		||||
		*pj++ = t;				\
 | 
			
		||||
        } while (--i > 0);				\
 | 
			
		||||
@@ -53,10 +62,12 @@ static __inline void	 swapfunc(char *, char *, int, int);
 | 
			
		||||
#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
 | 
			
		||||
	es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
 | 
			
		||||
 | 
			
		||||
static __inline void
 | 
			
		||||
swapfunc(char *a, char *b, int n, int swaptype)
 | 
			
		||||
static inline void
 | 
			
		||||
swapfunc(a, b, n, swaptype)
 | 
			
		||||
	char *a, *b;
 | 
			
		||||
	int n, swaptype;
 | 
			
		||||
{
 | 
			
		||||
	if (swaptype <= 1)
 | 
			
		||||
	if(swaptype <= 1)
 | 
			
		||||
		swapcode(long, a, b, n)
 | 
			
		||||
	else
 | 
			
		||||
		swapcode(char, a, b, n)
 | 
			
		||||
@@ -70,59 +81,77 @@ swapfunc(char *a, char *b, int n, int swaptype)
 | 
			
		||||
	} else						\
 | 
			
		||||
		swapfunc(a, b, es, swaptype)
 | 
			
		||||
 | 
			
		||||
#define vecswap(a, b, n)	if ((n) > 0) swapfunc(a, b, n, swaptype)
 | 
			
		||||
#define vecswap(a, b, n) 	if ((n) > 0) swapfunc(a, b, n, swaptype)
 | 
			
		||||
 | 
			
		||||
static __inline char *
 | 
			
		||||
med3(char *a, char *b, char *c, int (*cmp)(const void *, const void *))
 | 
			
		||||
#ifdef I_AM_QSORT_R
 | 
			
		||||
#define	CMP(t, x, y) (cmp((t), (x), (y)))
 | 
			
		||||
#else
 | 
			
		||||
#define	CMP(t, x, y) (cmp((x), (y)))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static inline char *
 | 
			
		||||
med3(char *a, char *b, char *c, cmp_t *cmp, void *thunk
 | 
			
		||||
#ifndef I_AM_QSORT_R
 | 
			
		||||
__unused
 | 
			
		||||
#endif
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	return cmp(a, b) < 0 ?
 | 
			
		||||
	       (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a ))
 | 
			
		||||
              :(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c ));
 | 
			
		||||
	return CMP(thunk, a, b) < 0 ?
 | 
			
		||||
	       (CMP(thunk, b, c) < 0 ? b : (CMP(thunk, a, c) < 0 ? c : a ))
 | 
			
		||||
              :(CMP(thunk, b, c) > 0 ? b : (CMP(thunk, a, c) < 0 ? a : c ));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef I_AM_QSORT_R
 | 
			
		||||
void
 | 
			
		||||
qsort(void *aa, size_t n, size_t es, int (*cmp)(const void *, const void *))
 | 
			
		||||
qsort_r(void *a, size_t n, size_t es, void *thunk, cmp_t *cmp)
 | 
			
		||||
#else
 | 
			
		||||
#define thunk NULL
 | 
			
		||||
void
 | 
			
		||||
qsort(void *a, size_t n, size_t es, cmp_t *cmp)
 | 
			
		||||
#endif
 | 
			
		||||
{
 | 
			
		||||
	char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
 | 
			
		||||
	int d, r, swaptype, swap_cnt;
 | 
			
		||||
	char *a = aa;
 | 
			
		||||
	size_t d, r;
 | 
			
		||||
	int cmp_result;
 | 
			
		||||
	int swaptype, swap_cnt;
 | 
			
		||||
 | 
			
		||||
loop:	SWAPINIT(a, es);
 | 
			
		||||
	swap_cnt = 0;
 | 
			
		||||
	if (n < 7) {
 | 
			
		||||
		for (pm = (char *)a + es; pm < (char *) a + n * es; pm += es)
 | 
			
		||||
			for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
 | 
			
		||||
		for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
 | 
			
		||||
			for (pl = pm; 
 | 
			
		||||
			     pl > (char *)a && CMP(thunk, pl - es, pl) > 0;
 | 
			
		||||
			     pl -= es)
 | 
			
		||||
				swap(pl, pl - es);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	pm = (char *)a + (n / 2) * es;
 | 
			
		||||
	if (n > 7) {
 | 
			
		||||
		pl = (char *)a;
 | 
			
		||||
		pl = a;
 | 
			
		||||
		pn = (char *)a + (n - 1) * es;
 | 
			
		||||
		if (n > 40) {
 | 
			
		||||
			d = (n / 8) * es;
 | 
			
		||||
			pl = med3(pl, pl + d, pl + 2 * d, cmp);
 | 
			
		||||
			pm = med3(pm - d, pm, pm + d, cmp);
 | 
			
		||||
			pn = med3(pn - 2 * d, pn - d, pn, cmp);
 | 
			
		||||
			pl = med3(pl, pl + d, pl + 2 * d, cmp, thunk);
 | 
			
		||||
			pm = med3(pm - d, pm, pm + d, cmp, thunk);
 | 
			
		||||
			pn = med3(pn - 2 * d, pn - d, pn, cmp, thunk);
 | 
			
		||||
		}
 | 
			
		||||
		pm = med3(pl, pm, pn, cmp);
 | 
			
		||||
		pm = med3(pl, pm, pn, cmp, thunk);
 | 
			
		||||
	}
 | 
			
		||||
	swap(a, pm);
 | 
			
		||||
	pa = pb = (char *)a + es;
 | 
			
		||||
 | 
			
		||||
	pc = pd = (char *)a + (n - 1) * es;
 | 
			
		||||
	for (;;) {
 | 
			
		||||
		while (pb <= pc && (r = cmp(pb, a)) <= 0) {
 | 
			
		||||
			if (r == 0) {
 | 
			
		||||
		while (pb <= pc && (cmp_result = CMP(thunk, pb, a)) <= 0) {
 | 
			
		||||
			if (cmp_result == 0) {
 | 
			
		||||
				swap_cnt = 1;
 | 
			
		||||
				swap(pa, pb);
 | 
			
		||||
				pa += es;
 | 
			
		||||
			}
 | 
			
		||||
			pb += es;
 | 
			
		||||
		}
 | 
			
		||||
		while (pb <= pc && (r = cmp(pc, a)) >= 0) {
 | 
			
		||||
			if (r == 0) {
 | 
			
		||||
		while (pb <= pc && (cmp_result = CMP(thunk, pc, a)) >= 0) {
 | 
			
		||||
			if (cmp_result == 0) {
 | 
			
		||||
				swap_cnt = 1;
 | 
			
		||||
				swap(pc, pd);
 | 
			
		||||
				pd -= es;
 | 
			
		||||
@@ -137,8 +166,9 @@ loop:	SWAPINIT(a, es);
 | 
			
		||||
		pc -= es;
 | 
			
		||||
	}
 | 
			
		||||
	if (swap_cnt == 0) {  /* Switch to insertion sort */
 | 
			
		||||
		for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
 | 
			
		||||
			for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
 | 
			
		||||
		for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
 | 
			
		||||
			for (pl = pm; 
 | 
			
		||||
			     pl > (char *)a && CMP(thunk, pl - es, pl) > 0;
 | 
			
		||||
			     pl -= es)
 | 
			
		||||
				swap(pl, pl - es);
 | 
			
		||||
		return;
 | 
			
		||||
@@ -147,15 +177,19 @@ loop:	SWAPINIT(a, es);
 | 
			
		||||
	pn = (char *)a + n * es;
 | 
			
		||||
	r = min(pa - (char *)a, pb - pa);
 | 
			
		||||
	vecswap(a, pb - r, r);
 | 
			
		||||
	r = min(pd - pc, pn - pd - (int)es);
 | 
			
		||||
	r = min(pd - pc, pn - pd - es);
 | 
			
		||||
	vecswap(pb, pn - r, r);
 | 
			
		||||
	if ((r = pb - pa) > (int)es)
 | 
			
		||||
	if ((r = pb - pa) > es)
 | 
			
		||||
#ifdef I_AM_QSORT_R
 | 
			
		||||
		qsort_r(a, r / es, es, thunk, cmp);
 | 
			
		||||
#else
 | 
			
		||||
		qsort(a, r / es, es, cmp);
 | 
			
		||||
	if ((r = pd - pc) > (int)es) {
 | 
			
		||||
#endif
 | 
			
		||||
	if ((r = pd - pc) > es) {
 | 
			
		||||
		/* Iterate rather than recurse to save stack space */
 | 
			
		||||
		a = pn - r;
 | 
			
		||||
		n = r / es;
 | 
			
		||||
		goto loop;
 | 
			
		||||
	}
 | 
			
		||||
	/* qsort(pn - r, r / es, es, cmp); */
 | 
			
		||||
/*		qsort(pn - r, r / es, es, cmp);*/
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										28
									
								
								libc/upstream-freebsd/libc_private.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								libc/upstream-freebsd/libc_private.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2013 The Android Open Source Project
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _BIONIC_FREEBSD_LIBC_PRIVATE_H_included
 | 
			
		||||
#define _BIONIC_FREEBSD_LIBC_PRIVATE_H_included
 | 
			
		||||
 | 
			
		||||
#define FLOCKFILE(fp)   do { if (__isthreaded) flockfile(fp); } while (0)
 | 
			
		||||
#define FUNLOCKFILE(fp) do { if (__isthreaded) funlockfile(fp); } while (0)
 | 
			
		||||
 | 
			
		||||
#define STDIO_THREAD_LOCK()   /* TODO: until we have the FreeBSD findfp.c, this is useless. */
 | 
			
		||||
#define STDIO_THREAD_UNLOCK() /* TODO: until we have the FreeBSD findfp.c, this is useless. */
 | 
			
		||||
 | 
			
		||||
#define ORIENT(fp, o) /* Only needed for wide-character stream support. */
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										22
									
								
								libc/upstream-freebsd/spinlock.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								libc/upstream-freebsd/spinlock.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2013 The Android Open Source Project
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _BIONIC_FREEBSD_SPINLOCK_H_included
 | 
			
		||||
#define _BIONIC_FREEBSD_SPINLOCK_H_included
 | 
			
		||||
 | 
			
		||||
/* TODO: until we have the FreeBSD findfp.c, this is useless. */
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							@@ -52,8 +52,12 @@ enum debugger_action_t {
 | 
			
		||||
 | 
			
		||||
/* message sent over the socket */
 | 
			
		||||
struct debugger_msg_t {
 | 
			
		||||
    debugger_action_t action;
 | 
			
		||||
    pid_t tid;
 | 
			
		||||
  // version 1 included:
 | 
			
		||||
  debugger_action_t action;
 | 
			
		||||
  pid_t tid;
 | 
			
		||||
 | 
			
		||||
  // version 2 added:
 | 
			
		||||
  uintptr_t abort_msg_address;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// see man(2) prctl, specifically the section about PR_GET_NAME
 | 
			
		||||
@@ -154,14 +158,14 @@ static bool haveSiginfo(int signum) {
 | 
			
		||||
    sigemptyset(&newact.sa_mask);
 | 
			
		||||
 | 
			
		||||
    if (sigaction(signum, &newact, &oldact) < 0) {
 | 
			
		||||
      __libc_format_log(ANDROID_LOG_FATAL, "libc", "Failed testing for SA_SIGINFO: %s",
 | 
			
		||||
      __libc_format_log(ANDROID_LOG_WARN, "libc", "Failed testing for SA_SIGINFO: %s",
 | 
			
		||||
                        strerror(errno));
 | 
			
		||||
      return 0;
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    bool ret = (oldact.sa_flags & SA_SIGINFO) != 0;
 | 
			
		||||
 | 
			
		||||
    if (sigaction(signum, &oldact, NULL) == -1) {
 | 
			
		||||
      __libc_format_log(ANDROID_LOG_FATAL, "libc", "Restore failed in test for SA_SIGINFO: %s",
 | 
			
		||||
      __libc_format_log(ANDROID_LOG_WARN, "libc", "Restore failed in test for SA_SIGINFO: %s",
 | 
			
		||||
                        strerror(errno));
 | 
			
		||||
    }
 | 
			
		||||
    return ret;
 | 
			
		||||
@@ -186,19 +190,17 @@ void debuggerd_signal_handler(int n, siginfo_t* info, void*) {
 | 
			
		||||
    int s = socket_abstract_client(DEBUGGER_SOCKET_NAME, SOCK_STREAM);
 | 
			
		||||
 | 
			
		||||
    if (s >= 0) {
 | 
			
		||||
        /* debugger knows our pid from the credentials on the
 | 
			
		||||
         * local socket but we need to tell it our tid.  It
 | 
			
		||||
         * is paranoid and will verify that we are giving a tid
 | 
			
		||||
         * that's actually in our process
 | 
			
		||||
         */
 | 
			
		||||
        int  ret;
 | 
			
		||||
        // debuggerd knows our pid from the credentials on the
 | 
			
		||||
        // local socket but we need to tell it the tid of the crashing thread.
 | 
			
		||||
        // debuggerd will be paranoid and verify that we sent a tid
 | 
			
		||||
        // that's actually in our process.
 | 
			
		||||
        debugger_msg_t msg;
 | 
			
		||||
        msg.action = DEBUGGER_ACTION_CRASH;
 | 
			
		||||
        msg.tid = tid;
 | 
			
		||||
        ret = TEMP_FAILURE_RETRY(write(s, &msg, sizeof(msg)));
 | 
			
		||||
        msg.abort_msg_address = reinterpret_cast<uintptr_t>(gAbortMessage);
 | 
			
		||||
        int ret = TEMP_FAILURE_RETRY(write(s, &msg, sizeof(msg)));
 | 
			
		||||
        if (ret == sizeof(msg)) {
 | 
			
		||||
            /* if the write failed, there is no point to read on
 | 
			
		||||
             * the file descriptor. */
 | 
			
		||||
            // if the write failed, there is no point trying to read a response.
 | 
			
		||||
            ret = TEMP_FAILURE_RETRY(read(s, &tid, 1));
 | 
			
		||||
            int saved_errno = errno;
 | 
			
		||||
            notify_gdb_of_libraries();
 | 
			
		||||
 
 | 
			
		||||
@@ -105,6 +105,8 @@ static soinfo* gLdPreloads[LDPRELOAD_MAX + 1];
 | 
			
		||||
 | 
			
		||||
__LIBC_HIDDEN__ int gLdDebugVerbosity;
 | 
			
		||||
 | 
			
		||||
__LIBC_HIDDEN__ abort_msg_t* gAbortMessage = NULL; // For debuggerd.
 | 
			
		||||
 | 
			
		||||
enum RelocationKind {
 | 
			
		||||
    kRelocAbsolute = 0,
 | 
			
		||||
    kRelocRelative,
 | 
			
		||||
@@ -171,8 +173,7 @@ size_t linker_get_error_buffer_size() {
 | 
			
		||||
 */
 | 
			
		||||
extern "C" void __attribute__((noinline)) __attribute__((visibility("default"))) rtld_db_dlactivity();
 | 
			
		||||
 | 
			
		||||
static r_debug _r_debug = {1, NULL, &rtld_db_dlactivity,
 | 
			
		||||
                                  RT_CONSISTENT, 0};
 | 
			
		||||
static r_debug _r_debug = {1, NULL, &rtld_db_dlactivity, RT_CONSISTENT, 0};
 | 
			
		||||
static link_map_t* r_debug_tail = 0;
 | 
			
		||||
 | 
			
		||||
static pthread_mutex_t gDebugMutex = PTHREAD_MUTEX_INITIALIZER;
 | 
			
		||||
@@ -1594,11 +1595,6 @@ static bool soinfo_link_image(soinfo* si) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If this is a setuid/setgid program, close the security hole described in
 | 
			
		||||
    // ftp://ftp.freebsd.org/pub/FreeBSD/CERT/advisories/FreeBSD-SA-02:23.stdio.asc
 | 
			
		||||
    if (get_AT_SECURE()) {
 | 
			
		||||
        nullify_closed_stdio();
 | 
			
		||||
    }
 | 
			
		||||
    notify_gdb_of_load(si);
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
@@ -1627,6 +1623,12 @@ static Elf32_Addr __linker_init_post_relocation(KernelArgumentBlock& args, Elf32
 | 
			
		||||
    // Initialize environment functions, and get to the ELF aux vectors table.
 | 
			
		||||
    linker_env_init(args);
 | 
			
		||||
 | 
			
		||||
    // If this is a setuid/setgid program, close the security hole described in
 | 
			
		||||
    // ftp://ftp.freebsd.org/pub/FreeBSD/CERT/advisories/FreeBSD-SA-02:23.stdio.asc
 | 
			
		||||
    if (get_AT_SECURE()) {
 | 
			
		||||
        nullify_closed_stdio();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    debuggerd_init();
 | 
			
		||||
 | 
			
		||||
    // Get a few environment variables.
 | 
			
		||||
@@ -1815,8 +1817,8 @@ extern "C" Elf32_Addr __linker_init(void* raw_args) {
 | 
			
		||||
 | 
			
		||||
  Elf32_Addr linker_addr = args.getauxval(AT_BASE);
 | 
			
		||||
 | 
			
		||||
  Elf32_Ehdr *elf_hdr = (Elf32_Ehdr*) linker_addr;
 | 
			
		||||
  Elf32_Phdr *phdr = (Elf32_Phdr*)((unsigned char*) linker_addr + elf_hdr->e_phoff);
 | 
			
		||||
  Elf32_Ehdr* elf_hdr = (Elf32_Ehdr*) linker_addr;
 | 
			
		||||
  Elf32_Phdr* phdr = (Elf32_Phdr*)((unsigned char*) linker_addr + elf_hdr->e_phoff);
 | 
			
		||||
 | 
			
		||||
  soinfo linker_so;
 | 
			
		||||
  memset(&linker_so, 0, sizeof(soinfo));
 | 
			
		||||
@@ -1841,6 +1843,7 @@ extern "C" Elf32_Addr __linker_init(void* raw_args) {
 | 
			
		||||
 | 
			
		||||
  // We have successfully fixed our own relocations. It's safe to run
 | 
			
		||||
  // the main part of the linker now.
 | 
			
		||||
  args.abort_message_ptr = &gAbortMessage;
 | 
			
		||||
  Elf32_Addr start_address = __linker_init_post_relocation(args, linker_addr);
 | 
			
		||||
 | 
			
		||||
  set_soinfo_pool_protection(PROT_READ);
 | 
			
		||||
 
 | 
			
		||||
@@ -186,6 +186,7 @@ Elf32_Sym* dladdr_find_symbol(soinfo* si, const void* addr);
 | 
			
		||||
Elf32_Sym* dlsym_handle_lookup(soinfo* si, const char* name);
 | 
			
		||||
 | 
			
		||||
void debuggerd_init();
 | 
			
		||||
extern "C" abort_msg_t* gAbortMessage;
 | 
			
		||||
extern "C" void notify_gdb_of_libraries();
 | 
			
		||||
 | 
			
		||||
char* linker_get_error_buffer();
 | 
			
		||||
 
 | 
			
		||||
@@ -58,7 +58,10 @@ test_c_flags = \
 | 
			
		||||
 | 
			
		||||
test_src_files = \
 | 
			
		||||
    dirent_test.cpp \
 | 
			
		||||
    eventfd_test.cpp \
 | 
			
		||||
    fenv_test.cpp \
 | 
			
		||||
    fortify1_test.cpp \
 | 
			
		||||
    fortify2_test.cpp \
 | 
			
		||||
    getauxval_test.cpp \
 | 
			
		||||
    getcwd_test.cpp \
 | 
			
		||||
    libc_logging_test.cpp \
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										47
									
								
								tests/eventfd_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								tests/eventfd_test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2013 The Android Open Source Project
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <gtest/gtest.h>
 | 
			
		||||
 | 
			
		||||
#if !defined(__GLIBC__) // Android's prebuilt gcc's header files don't include <sys/eventfd.h>.
 | 
			
		||||
 | 
			
		||||
#include <sys/eventfd.h>
 | 
			
		||||
 | 
			
		||||
TEST(eventfd, smoke) {
 | 
			
		||||
  unsigned int initial_value = 2;
 | 
			
		||||
  int fd = eventfd(initial_value, O_NONBLOCK);
 | 
			
		||||
  ASSERT_NE(fd, -1);
 | 
			
		||||
 | 
			
		||||
  eventfd_t value = 123;
 | 
			
		||||
  ASSERT_EQ(0, eventfd_read(fd, &value));
 | 
			
		||||
  ASSERT_EQ(initial_value, value);
 | 
			
		||||
 | 
			
		||||
  // Reading clears the counter.
 | 
			
		||||
  ASSERT_EQ(-1, eventfd_read(fd, &value));
 | 
			
		||||
  ASSERT_EQ(EAGAIN, errno);
 | 
			
		||||
 | 
			
		||||
  // Values written are added until the next read.
 | 
			
		||||
  ASSERT_EQ(0, eventfd_write(fd, 1));
 | 
			
		||||
  ASSERT_EQ(0, eventfd_write(fd, 1));
 | 
			
		||||
  ASSERT_EQ(0, eventfd_write(fd, 1));
 | 
			
		||||
 | 
			
		||||
  ASSERT_EQ(0, eventfd_read(fd, &value));
 | 
			
		||||
  ASSERT_EQ(3U, value);
 | 
			
		||||
 | 
			
		||||
  close(fd);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										62
									
								
								tests/fortify1_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								tests/fortify1_test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2013 The Android Open Source Project
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#undef _FORTIFY_SOURCE
 | 
			
		||||
#define _FORTIFY_SOURCE 1
 | 
			
		||||
 | 
			
		||||
#include <gtest/gtest.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#if __BIONIC__
 | 
			
		||||
// We have to say "DeathTest" here so gtest knows to run this test (which exits)
 | 
			
		||||
// in its own process.
 | 
			
		||||
TEST(Fortify1_DeathTest, strcpy_fortified) {
 | 
			
		||||
  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
 | 
			
		||||
  char buf[10];
 | 
			
		||||
  char *orig = strdup("0123456789");
 | 
			
		||||
  ASSERT_EXIT(strcpy(buf, orig), testing::KilledBySignal(SIGSEGV), "");
 | 
			
		||||
  free(orig);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(Fortify1_DeathTest, strlen_fortified) {
 | 
			
		||||
  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
 | 
			
		||||
  char buf[10];
 | 
			
		||||
  memcpy(buf, "0123456789", sizeof(buf));
 | 
			
		||||
  ASSERT_EXIT(printf("%d", strlen(buf)), testing::KilledBySignal(SIGSEGV), "");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(Fortify1_DeathTest, strchr_fortified) {
 | 
			
		||||
  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
 | 
			
		||||
  char buf[10];
 | 
			
		||||
  memcpy(buf, "0123456789", sizeof(buf));
 | 
			
		||||
  ASSERT_EXIT(printf("%s", strchr(buf, 'a')), testing::KilledBySignal(SIGSEGV), "");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(Fortify1_DeathTest, strrchr_fortified) {
 | 
			
		||||
  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
 | 
			
		||||
  char buf[10];
 | 
			
		||||
  memcpy(buf, "0123456789", sizeof(buf));
 | 
			
		||||
  ASSERT_EXIT(printf("%s", strrchr(buf, 'a')), testing::KilledBySignal(SIGSEGV), "");
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
TEST(Fortify1_DeathTest, sprintf_fortified) {
 | 
			
		||||
  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
 | 
			
		||||
  char buf[10];
 | 
			
		||||
  char source_buf[15];
 | 
			
		||||
  memcpy(source_buf, "12345678901234", 15);
 | 
			
		||||
  ASSERT_EXIT(sprintf(buf, "%s", source_buf), testing::KilledBySignal(SIGSEGV), "");
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										108
									
								
								tests/fortify2_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								tests/fortify2_test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,108 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2013 The Android Open Source Project
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#undef _FORTIFY_SOURCE
 | 
			
		||||
#define _FORTIFY_SOURCE 2
 | 
			
		||||
 | 
			
		||||
#include <gtest/gtest.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
struct foo {
 | 
			
		||||
  char a[10];
 | 
			
		||||
  char b[10];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// We have to say "DeathTest" here so gtest knows to run this test (which exits)
 | 
			
		||||
// in its own process.
 | 
			
		||||
TEST(Fortify2_DeathTest, strncpy_fortified2) {
 | 
			
		||||
  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
 | 
			
		||||
  foo myfoo;
 | 
			
		||||
  int copy_amt = atoi("11");
 | 
			
		||||
  ASSERT_EXIT(strncpy(myfoo.a, "01234567890", copy_amt),
 | 
			
		||||
              testing::KilledBySignal(SIGSEGV), "");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(Fortify2_DeathTest, sprintf_fortified2) {
 | 
			
		||||
  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
 | 
			
		||||
  foo myfoo;
 | 
			
		||||
  char source_buf[15];
 | 
			
		||||
  memcpy(source_buf, "12345678901234", 15);
 | 
			
		||||
  ASSERT_EXIT(sprintf(myfoo.a, "%s", source_buf),
 | 
			
		||||
              testing::KilledBySignal(SIGSEGV), "");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if __BIONIC__
 | 
			
		||||
TEST(Fortify2_DeathTest, strchr_fortified2) {
 | 
			
		||||
  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
 | 
			
		||||
  foo myfoo;
 | 
			
		||||
  memcpy(myfoo.a, "0123456789", sizeof(myfoo.a));
 | 
			
		||||
  myfoo.b[0] = '\0';
 | 
			
		||||
  ASSERT_EXIT(printf("%s", strchr(myfoo.a, 'a')),
 | 
			
		||||
              testing::KilledBySignal(SIGSEGV), "");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(Fortify2_DeathTest, strrchr_fortified2) {
 | 
			
		||||
  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
 | 
			
		||||
  foo myfoo;
 | 
			
		||||
  memcpy(myfoo.a, "0123456789", 10);
 | 
			
		||||
  memcpy(myfoo.b, "01234", 6);
 | 
			
		||||
  ASSERT_EXIT(printf("%s", strrchr(myfoo.a, 'a')),
 | 
			
		||||
              testing::KilledBySignal(SIGSEGV), "");
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/***********************************************************/
 | 
			
		||||
/* TESTS BELOW HERE DUPLICATE TESTS FROM fortify1_test.cpp */
 | 
			
		||||
/***********************************************************/
 | 
			
		||||
 | 
			
		||||
#if __BIONIC__
 | 
			
		||||
TEST(Fortify2_DeathTest, strcpy_fortified) {
 | 
			
		||||
  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
 | 
			
		||||
  char buf[10];
 | 
			
		||||
  char *orig = strdup("0123456789");
 | 
			
		||||
  ASSERT_EXIT(strcpy(buf, orig), testing::KilledBySignal(SIGSEGV), "");
 | 
			
		||||
  free(orig);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(Fortify2_DeathTest, strlen_fortified) {
 | 
			
		||||
  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
 | 
			
		||||
  char buf[10];
 | 
			
		||||
  memcpy(buf, "0123456789", sizeof(buf));
 | 
			
		||||
  ASSERT_EXIT(printf("%d", strlen(buf)), testing::KilledBySignal(SIGSEGV), "");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(Fortify2_DeathTest, strchr_fortified) {
 | 
			
		||||
  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
 | 
			
		||||
  char buf[10];
 | 
			
		||||
  memcpy(buf, "0123456789", sizeof(buf));
 | 
			
		||||
  ASSERT_EXIT(printf("%s", strchr(buf, 'a')), testing::KilledBySignal(SIGSEGV), "");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(Fortify2_DeathTest, strrchr_fortified) {
 | 
			
		||||
  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
 | 
			
		||||
  char buf[10];
 | 
			
		||||
  memcpy(buf, "0123456789", sizeof(buf));
 | 
			
		||||
  ASSERT_EXIT(printf("%s", strrchr(buf, 'a')), testing::KilledBySignal(SIGSEGV), "");
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
TEST(Fortify2_DeathTest, sprintf_fortified) {
 | 
			
		||||
  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
 | 
			
		||||
  char buf[10];
 | 
			
		||||
  char source_buf[15];
 | 
			
		||||
  memcpy(source_buf, "12345678901234", 15);
 | 
			
		||||
  ASSERT_EXIT(sprintf(buf, "%s", source_buf), testing::KilledBySignal(SIGSEGV), "");
 | 
			
		||||
}
 | 
			
		||||
@@ -193,3 +193,21 @@ TEST(stdio, popen) {
 | 
			
		||||
 | 
			
		||||
  ASSERT_EQ(0, pclose(fp));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(stdio, getc) {
 | 
			
		||||
  FILE* fp = fopen("/proc/version", "r");
 | 
			
		||||
  ASSERT_TRUE(fp != NULL);
 | 
			
		||||
  ASSERT_EQ('L', getc(fp));
 | 
			
		||||
  ASSERT_EQ('i', getc(fp));
 | 
			
		||||
  ASSERT_EQ('n', getc(fp));
 | 
			
		||||
  ASSERT_EQ('u', getc(fp));
 | 
			
		||||
  ASSERT_EQ('x', getc(fp));
 | 
			
		||||
  fclose(fp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(stdio, putc) {
 | 
			
		||||
  FILE* fp = fopen("/proc/version", "r");
 | 
			
		||||
  ASSERT_TRUE(fp != NULL);
 | 
			
		||||
  ASSERT_EQ(EOF, putc('x', fp));
 | 
			
		||||
  fclose(fp);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -109,3 +109,26 @@ TEST(stdlib, realpath) {
 | 
			
		||||
  ASSERT_STREQ(executable_path, p);
 | 
			
		||||
  free(p);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(stdlib, qsort) {
 | 
			
		||||
  struct s {
 | 
			
		||||
    char name[16];
 | 
			
		||||
    static int comparator(const void* lhs, const void* rhs) {
 | 
			
		||||
      return strcmp(reinterpret_cast<const s*>(lhs)->name, reinterpret_cast<const s*>(rhs)->name);
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
  s entries[3];
 | 
			
		||||
  strcpy(entries[0].name, "charlie");
 | 
			
		||||
  strcpy(entries[1].name, "bravo");
 | 
			
		||||
  strcpy(entries[2].name, "alpha");
 | 
			
		||||
 | 
			
		||||
  qsort(entries, 3, sizeof(s), s::comparator);
 | 
			
		||||
  ASSERT_STREQ("alpha", entries[0].name);
 | 
			
		||||
  ASSERT_STREQ("bravo", entries[1].name);
 | 
			
		||||
  ASSERT_STREQ("charlie", entries[2].name);
 | 
			
		||||
 | 
			
		||||
  qsort(entries, 3, sizeof(s), s::comparator);
 | 
			
		||||
  ASSERT_STREQ("alpha", entries[0].name);
 | 
			
		||||
  ASSERT_STREQ("bravo", entries[1].name);
 | 
			
		||||
  ASSERT_STREQ("charlie", entries[2].name);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -209,6 +209,13 @@ TEST(string, strcat) {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(string, strchr_with_0) {
 | 
			
		||||
  char buf[10];
 | 
			
		||||
  const char* s = "01234";
 | 
			
		||||
  memcpy(buf, s, strlen(s) + 1);
 | 
			
		||||
  EXPECT_TRUE(strchr(buf, '\0') == (buf + strlen(s)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(string, strchr) {
 | 
			
		||||
  int seek_char = random() & 255;
 | 
			
		||||
 | 
			
		||||
@@ -306,39 +313,6 @@ TEST(string, strcpy) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if __BIONIC__
 | 
			
		||||
// We have to say "DeathTest" here so gtest knows to run this test (which exits)
 | 
			
		||||
// in its own process.
 | 
			
		||||
TEST(string_DeathTest, strcpy_fortified) {
 | 
			
		||||
  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
 | 
			
		||||
  char buf[10];
 | 
			
		||||
  char *orig = strdup("0123456789");
 | 
			
		||||
  ASSERT_EXIT(strcpy(buf, orig), testing::KilledBySignal(SIGSEGV), "");
 | 
			
		||||
  free(orig);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(string_DeathTest, strlen_fortified) {
 | 
			
		||||
  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
 | 
			
		||||
  char buf[10];
 | 
			
		||||
  memcpy(buf, "0123456789", sizeof(buf));
 | 
			
		||||
  ASSERT_EXIT(printf("%d", strlen(buf)), testing::KilledBySignal(SIGSEGV), "");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(string_DeathTest, strchr_fortified) {
 | 
			
		||||
  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
 | 
			
		||||
  char buf[10];
 | 
			
		||||
  memcpy(buf, "0123456789", sizeof(buf));
 | 
			
		||||
  ASSERT_EXIT(printf("%s", strchr(buf, 'a')), testing::KilledBySignal(SIGSEGV), "");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(string_DeathTest, strrchr_fortified) {
 | 
			
		||||
  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
 | 
			
		||||
  char buf[10];
 | 
			
		||||
  memcpy(buf, "0123456789", sizeof(buf));
 | 
			
		||||
  ASSERT_EXIT(printf("%s", strrchr(buf, 'a')), testing::KilledBySignal(SIGSEGV), "");
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if __BIONIC__
 | 
			
		||||
TEST(string, strlcat) {
 | 
			
		||||
  StringTestState state(SMALL);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user