123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315 |
- /*
- * Copyright (C) 2000-2005 by Erik Andersen <andersen@codepoet.org>
- *
- * GNU Lesser General Public License version 2.1 or later.
- */
- #ifndef _DL_SYSCALL_H
- #define _DL_SYSCALL_H
- /* We can't use the real errno in ldso, since it has not yet
- * been dynamicly linked in yet. */
- #include "sys/syscall.h"
- extern int _dl_errno;
- #undef __set_errno
- #define __set_errno(X) {(_dl_errno) = (X);}
- /* Pull in the arch specific syscall implementation */
- #include <dl-syscalls.h>
- /* For MAP_ANONYMOUS -- differs between platforms */
- #define _SYS_MMAN_H 1
- #include <bits/mman.h>
- #ifdef __ARCH_HAS_DEPRECATED_SYSCALLS__
- /* Pull in whatever this particular arch's kernel thinks the kernel version of
- * struct stat should look like. It turns out that each arch has a different
- * opinion on the subject, and different kernel revs use different names... */
- #define kernel_stat stat
- #include <bits/kernel_stat.h>
- #include <bits/kernel_types.h>
- /* Protection bits. */
- #define S_ISUID 04000 /* Set user ID on execution. */
- #define S_ISGID 02000 /* Set group ID on execution. */
- #else
- /* 1. common-generic ABI doesn't need kernel_stat translation
- * 3. S_IS?ID already provided by stat.h
- */
- #include <fcntl.h>
- #include <sys/stat.h>
- #include <dl-string.h>
- #include <bits/uClibc_arch_features.h>
- #if defined __UCLIBC_HAVE_STATX__
- static __always_inline void
- __cp_stat_statx (struct stat *to, struct statx *from)
- {
- _dl_memset (to, 0, sizeof (struct stat));
- to->st_dev = ((from->stx_dev_minor & 0xff) | (from->stx_dev_major << 8)
- | ((from->stx_dev_minor & ~0xff) << 12));
- to->st_rdev = ((from->stx_rdev_minor & 0xff) | (from->stx_rdev_major << 8)
- | ((from->stx_rdev_minor & ~0xff) << 12));
- to->st_ino = from->stx_ino;
- to->st_mode = from->stx_mode;
- to->st_nlink = from->stx_nlink;
- to->st_uid = from->stx_uid;
- to->st_gid = from->stx_gid;
- to->st_atime = from->stx_atime.tv_sec;
- to->st_atim.tv_nsec = from->stx_atime.tv_nsec;
- to->st_mtime = from->stx_mtime.tv_sec;
- to->st_mtim.tv_nsec = from->stx_mtime.tv_nsec;
- to->st_ctime = from->stx_ctime.tv_sec;
- to->st_ctim.tv_nsec = from->stx_ctime.tv_nsec;
- to->st_size = from->stx_size;
- to->st_blocks = from->stx_blocks;
- to->st_blksize = from->stx_blksize;
- }
- #endif
- #endif
- #define AT_NO_AUTOMOUNT 0x800
- #define AT_EMPTY_PATH 0x1000
- /* Here are the definitions for some syscalls that are used
- by the dynamic linker. The idea is that we want to be able
- to call these before the errno symbol is dynamicly linked, so
- we use our own version here. Note that we cannot assume any
- dynamic linking at all, so we cannot return any error codes.
- We just punt if there is an error. */
- #define __NR__dl_exit __NR_exit
- static __always_inline attribute_noreturn __cold void _dl_exit(int status)
- {
- INLINE_SYSCALL(_dl_exit, 1, status);
- #if __GNUC_PREREQ(4, 5)
- __builtin_unreachable(); /* shut up warning: 'noreturn' function does return*/
- #else
- while (1);
- #endif
- }
- #define __NR__dl_close __NR_close
- static __always_inline _syscall1(int, _dl_close, int, fd)
- #if defined __NR_openat && !defined __NR_open
- static __always_inline int _dl_open(const char *fn,
- int flags, __kernel_mode_t mode)
- {
- return INLINE_SYSCALL(openat, 4, AT_FDCWD, fn, flags, mode);
- }
- #elif defined __NR_open
- # define __NR__dl_open __NR_open
- static __always_inline _syscall3(int, _dl_open, const char *, fn, int, flags,
- __kernel_mode_t, mode)
- #endif
- #define __NR__dl_write __NR_write
- static __always_inline _syscall3(unsigned long, _dl_write, int, fd,
- const void *, buf, unsigned long, count)
- #define __NR__dl_read __NR_read
- static __always_inline _syscall3(unsigned long, _dl_read, int, fd,
- const void *, buf, unsigned long, count)
- #define __NR__dl_mprotect __NR_mprotect
- static __always_inline _syscall3(int, _dl_mprotect, const void *, addr,
- unsigned long, len, int, prot)
- #if defined __NR_fstatat64 && !defined __NR_stat
- # define __NR__dl_fstatat64 __NR_fstatat64
- static __always_inline _syscall4(int, _dl_fstatat64, int, fd, const char *,
- fn, struct stat *, stat, int, flags)
- static __always_inline int _dl_stat(const char *file_name,
- struct stat *buf)
- {
- return _dl_fstatat64(AT_FDCWD, file_name, buf, 0);
- }
- #elif defined __NR_newfstatat && !defined __NR_stat
- # define __NR__dl_newfstatat __NR_newfstatat
- static __always_inline _syscall4(int, _dl_newfstatat, int, fd, const char *,
- fn, struct stat *, stat, int, flags)
- static __always_inline int _dl_stat(const char *file_name,
- struct stat *buf)
- {
- return _dl_newfstatat(AT_FDCWD, file_name, buf, 0);
- }
- #elif defined __NR_stat
- # define __NR__dl_stat __NR_stat
- static __always_inline _syscall2(int, _dl_stat, const char *, file_name,
- struct stat *, buf)
- #elif defined __NR_statx && defined __UCLIBC_HAVE_STATX__
- # define __NR__dl_statx __NR_statx
- # include <fcntl.h>
- # include <statx_cp.h>
- static __always_inline _syscall5(int, _dl_statx, int, fd, const char *, file_name, int, flags,
- unsigned int, mask, struct statx *, buf);
- static __always_inline int _dl_stat(const char *file_name,
- struct stat *buf)
- {
- struct statx tmp;
- int rc = _dl_statx(AT_FDCWD, file_name, AT_NO_AUTOMOUNT, STATX_BASIC_STATS, &tmp);
- if (rc == 0)
- __cp_stat_statx ((struct stat *)buf, &tmp);
- return rc;
- }
- #endif
- #if defined __NR_fstat64 && !defined __NR_fstat
- # define __NR__dl_fstat __NR_fstat64
- static __always_inline _syscall2(int, _dl_fstat, int, fd, struct stat *, buf)
- #elif defined __NR_fstat
- # define __NR__dl_fstat __NR_fstat
- static __always_inline _syscall2(int, _dl_fstat, int, fd, struct stat *, buf)
- #elif defined __NR_statx && defined __UCLIBC_HAVE_STATX__
- # define __NR__dl_fstatx __NR_statx
- static __always_inline _syscall5(int, _dl_fstatx, int, fd, const char *, file_name, int, flags, unsigned int, mask, struct stat *, buf);
- static __always_inline int _dl_fstat(int fd,
- struct stat *buf)
- {
- struct statx tmp;
- int rc = _dl_fstatx(fd, "", AT_EMPTY_PATH, STATX_BASIC_STATS, &tmp);
- if (rc == 0)
- __cp_stat_statx ((struct stat *)buf, &tmp);
- return rc;
- }
- #else
- static __always_inline _syscall2(int, _dl_fstat, int, fd, struct stat *, buf)
- #endif
- #define __NR__dl_munmap __NR_munmap
- static __always_inline _syscall2(int, _dl_munmap, void *, start, unsigned long, length)
- #ifdef __NR_getxuid
- # define __NR_getuid __NR_getxuid
- #endif
- #define __NR__dl_getuid __NR_getuid
- static __always_inline _syscall0(uid_t, _dl_getuid)
- #ifndef __NR_geteuid
- # define __NR_geteuid __NR_getuid
- #endif
- #define __NR__dl_geteuid __NR_geteuid
- static __always_inline _syscall0(uid_t, _dl_geteuid)
- #ifdef __NR_getxgid
- # define __NR_getgid __NR_getxgid
- #endif
- #define __NR__dl_getgid __NR_getgid
- static __always_inline _syscall0(gid_t, _dl_getgid)
- #ifndef __NR_getegid
- # define __NR_getegid __NR_getgid
- #endif
- #define __NR__dl_getegid __NR_getegid
- static __always_inline _syscall0(gid_t, _dl_getegid)
- #ifdef __NR_getxpid
- # define __NR_getpid __NR_getxpid
- #endif
- #define __NR__dl_getpid __NR_getpid
- static __always_inline _syscall0(gid_t, _dl_getpid)
- #if defined __NR_readlinkat
- # define __NR__dl_readlink __NR_readlinkat
- static __always_inline _syscall4(int, _dl_readlink, int, id, const char *, path,
- char *, buf, size_t, bufsiz)
- #endif
- #ifdef __NR_pread64
- #define __NR___syscall_pread __NR_pread64
- #ifdef __UCLIBC_SYSCALL_ALIGN_64BIT__
- static __always_inline _syscall6(ssize_t, __syscall_pread, int, fd, void *, buf, size_t, dummy,
- size_t, count, off_t, offset_hi, off_t, offset_lo)
- static __always_inline ssize_t
- _dl_pread(int fd, void *buf, size_t count, off_t offset)
- {
- return __syscall_pread(fd, buf, count, 0, __LONG_LONG_PAIR((offset >> 32), (offset & 0xffffffff)));
- }
- #else
- static __always_inline _syscall5(ssize_t, __syscall_pread, int, fd, void *, buf,
- size_t, count, off_t, offset_hi, off_t, offset_lo)
- static __always_inline ssize_t
- _dl_pread(int fd, void *buf, size_t count, off_t offset)
- {
- return __syscall_pread(fd, buf, count, __LONG_LONG_PAIR(offset >> 31, offset));
- }
- #endif
- #elif defined __NR_pread
- #define __NR___syscall_pread __NR_pread
- static __always_inline _syscall5(ssize_t, __syscall_pread, int, fd, void *, buf,
- size_t, count, off_t, offset_hi, off_t, offset_lo)
- static __always_inline ssize_t
- _dl_pread(int fd, void *buf, size_t count, off_t offset)
- {
- return __syscall_pread(fd, buf, count, __LONG_LONG_PAIR(offset >> 31, offset));
- }
- #endif
- #ifdef __UCLIBC_HAS_SSP__
- # include <sys/time.h>
- # define __NR__dl_gettimeofday __NR_gettimeofday
- static __always_inline _syscall2(int, _dl_gettimeofday, struct timeval *, tv,
- # ifdef __USE_BSD
- struct timezone *
- # else
- void *
- # endif
- , tz)
- #endif
- /* Some architectures always use 12 as page shift for mmap2() eventhough the
- * real PAGE_SHIFT != 12. Other architectures use the same value as
- * PAGE_SHIFT...
- */
- #ifndef MMAP2_PAGE_SHIFT
- # define MMAP2_PAGE_SHIFT 12
- #endif
- #define MAP_FAILED ((void *) -1)
- #define _dl_mmap_check_error(X) (((void *)X) == MAP_FAILED)
- static __always_inline
- void *_dl_mmap(void *addr, unsigned long size, int prot,
- int flags, int fd, unsigned long offset)
- {
- #if defined(__UCLIBC_MMAP_HAS_6_ARGS__) && defined(__NR_mmap)
- /* first try mmap(), syscall6() style */
- return (void *)INLINE_SYSCALL(mmap, 6, addr, size, prot, flags, fd, offset);
- #elif defined(__NR_mmap2) && !defined (__mcoldfire__)
- /* then try mmap2() */
- unsigned long shifted;
- if (offset & ((1 << MMAP2_PAGE_SHIFT) - 1))
- return MAP_FAILED;
- /* gcc needs help with putting things onto the stack */
- shifted = offset >> MMAP2_PAGE_SHIFT;
- return (void *)INLINE_SYSCALL(mmap2, 6, addr, size, prot, flags, fd, shifted);
- #elif defined(__NR_mmap)
- /* finally, fall back to mmap(), syscall1() style */
- unsigned long buffer[6];
- buffer[0] = (unsigned long) addr;
- buffer[1] = (unsigned long) size;
- buffer[2] = (unsigned long) prot;
- buffer[3] = (unsigned long) flags;
- buffer[4] = (unsigned long) fd;
- buffer[5] = (unsigned long) offset;
- return (void *)INLINE_SYSCALL(mmap, 1, buffer);
- #else
- # error "Your architecture doesn't seem to provide mmap() !?"
- #endif
- }
- #endif /* _DL_SYSCALL_H */
|