From: Rich Felker <dalias@libc.org>
To: musl@lists.openwall.com
Subject: [UGLY PATCH] Support for no-legacy-syscalls archs
Date: Sun, 25 May 2014 01:42:37 -0400 [thread overview]
Message-ID: <20140525054237.GA18085@brightrain.aerifal.cx> (raw)
[-- Attachment #1: Type: text/plain, Size: 359 bytes --]
Here's a proposed next phase for supporting no-legacy-syscall archs
(aarch64 and or1k, among others). It's not complete but I think it
covers most of the important syscalls for standard functionality (not
linux-specific stuff tho). Some of them might be missing some error
cases or otherwise buggy so I'm sending the patch for review before
committing.
Rich
[-- Attachment #2: no_legacy_syscall_archs.diff --]
[-- Type: text/plain, Size: 10361 bytes --]
diff --git a/src/env/__libc_start_main.c b/src/env/__libc_start_main.c
index d7481c2..f98a858 100644
--- a/src/env/__libc_start_main.c
+++ b/src/env/__libc_start_main.c
@@ -1,6 +1,7 @@
#include <elf.h>
#include <poll.h>
#include <fcntl.h>
+#include <signal.h>
#include "syscall.h"
#include "atomic.h"
#include "libc.h"
@@ -48,7 +49,11 @@ void __init_libc(char **envp, char *pn)
&& !aux[AT_SECURE]) return;
struct pollfd pfd[3] = { {.fd=0}, {.fd=1}, {.fd=2} };
+#ifdef SYS_poll
__syscall(SYS_poll, pfd, 3, 0);
+#else
+ __syscall(SYS_ppoll, pfd, 3, 0, 0, _NSIG/8);
+#endif
for (i=0; i<3; i++) if (pfd[i].revents&POLLNVAL)
if (__sys_open("/dev/null", O_RDWR)<0)
a_crash();
diff --git a/src/process/fork.c b/src/process/fork.c
index 864c7d7..89b04c6 100644
--- a/src/process/fork.c
+++ b/src/process/fork.c
@@ -1,5 +1,6 @@
#include <unistd.h>
#include <string.h>
+#include <signal.h>
#include "syscall.h"
#include "libc.h"
#include "pthread_impl.h"
@@ -16,7 +17,11 @@ pid_t fork(void)
sigset_t set;
__fork_handler(-1);
__block_all_sigs(&set);
+#ifdef SYS_fork
ret = syscall(SYS_fork);
+#else
+ ret = syscall(SYS_clone, SIGCHLD);
+#endif
if (libc.has_thread_pointer && !ret) {
pthread_t self = __pthread_self();
self->tid = self->pid = __syscall(SYS_getpid);
diff --git a/src/select/poll.c b/src/select/poll.c
index f1e73e8..4f13cfb 100644
--- a/src/select/poll.c
+++ b/src/select/poll.c
@@ -4,5 +4,11 @@
int poll(struct pollfd *fds, nfds_t n, int timeout)
{
+#ifdef SYS_poll
return syscall_cp(SYS_poll, fds, n, timeout);
+#else
+ return syscall_cp(SYS_ppoll, fds, n,
+ &(struct timespec){ .tv_sec = timeout/1000,
+ .tv_nsec = timeout%1000*1000000 }, 0, _NSIG/8);
+#endif
}
diff --git a/src/select/select.c b/src/select/select.c
index f93597b..5e7fe1f 100644
--- a/src/select/select.c
+++ b/src/select/select.c
@@ -4,5 +4,15 @@
int select(int n, fd_set *restrict rfds, fd_set *restrict wfds, fd_set *restrict efds, struct timeval *restrict tv)
{
+#ifdef SYS_select
return syscall_cp(SYS_select, n, rfds, wfds, efds, tv);
+#else
+ long data[2] = { 0, _NSIG/8 };
+ struct timespec ts;
+ if (tv) {
+ ts.tv_sec = tv->tv_sec;
+ ts.tv_nsec = tv->tv_usec * 1000;
+ }
+ return syscall_cp(SYS_pselect6, n, rfds, wfds, efds, tv ? &ts : 0, data);
+#endif
}
diff --git a/src/stat/chmod.c b/src/stat/chmod.c
index beb66e5..d4f53c5 100644
--- a/src/stat/chmod.c
+++ b/src/stat/chmod.c
@@ -1,7 +1,12 @@
#include <sys/stat.h>
+#include <fcntl.h>
#include "syscall.h"
int chmod(const char *path, mode_t mode)
{
+#ifdef SYS_chmod
return syscall(SYS_chmod, path, mode);
+#else
+ return syscall(SYS_fchmodat, AT_FDCWD, path, mode);
+#endif
}
diff --git a/src/stat/futimesat.c b/src/stat/futimesat.c
index dbefc84..ad33484 100644
--- a/src/stat/futimesat.c
+++ b/src/stat/futimesat.c
@@ -2,9 +2,18 @@
#include <sys/time.h>
#include "syscall.h"
-#ifdef SYS_futimesat
int futimesat(int dirfd, const char *pathname, const struct timeval times[2])
{
+#ifdef SYS_futimesat
return syscall(SYS_futimesat, dirfd, pathname, times);
-}
+#else
+ struct timespec ts[2];
+ if (times) {
+ ts[0].tv_sec = times[0].tv_sec;
+ ts[0].tv_nsec = times[0].tv_usec * 1000;
+ ts[1].tv_sec = times[1].tv_sec;
+ ts[1].tv_nsec = times[1].tv_usec * 1000;
+ }
+ return syscall(SYS_utimensat, dirfd, pathname, times ? ts : 0, 0);
#endif
+}
diff --git a/src/stat/lstat.c b/src/stat/lstat.c
index 8f60358..5e8b84f 100644
--- a/src/stat/lstat.c
+++ b/src/stat/lstat.c
@@ -1,10 +1,15 @@
#include <sys/stat.h>
+#include <fcntl.h>
#include "syscall.h"
#include "libc.h"
int lstat(const char *restrict path, struct stat *restrict buf)
{
+#ifdef SYS_lstat
return syscall(SYS_lstat, path, buf);
+#else
+ return syscall(SYS_fstatat, AT_FDCWD, path, buf, AT_SYMLINK_NOFOLLOW);
+#endif
}
LFS64(lstat);
diff --git a/src/stat/mkdir.c b/src/stat/mkdir.c
index 770e1cc..32625b7 100644
--- a/src/stat/mkdir.c
+++ b/src/stat/mkdir.c
@@ -1,7 +1,12 @@
#include <sys/stat.h>
+#include <fcntl.h>
#include "syscall.h"
int mkdir(const char *path, mode_t mode)
{
+#ifdef SYS_mkdir
return syscall(SYS_mkdir, path, mode);
+#else
+ return syscall(SYS_mkdirat, AT_FDCWD, path, mode);
+#endif
}
diff --git a/src/stat/mknod.c b/src/stat/mknod.c
index c319657..beebd84 100644
--- a/src/stat/mknod.c
+++ b/src/stat/mknod.c
@@ -1,7 +1,12 @@
#include <sys/stat.h>
+#include <fcntl.h>
#include "syscall.h"
int mknod(const char *path, mode_t mode, dev_t dev)
{
+#ifdef SYS_mknod
return syscall(SYS_mknod, path, mode, dev);
+#else
+ return syscall(SYS_mknodat, AT_FDCWD, path, mode, dev);
+#endif
}
diff --git a/src/stat/stat.c b/src/stat/stat.c
index c6de716..b4433a0 100644
--- a/src/stat/stat.c
+++ b/src/stat/stat.c
@@ -1,10 +1,15 @@
#include <sys/stat.h>
+#include <fcntl.h>
#include "syscall.h"
#include "libc.h"
int stat(const char *restrict path, struct stat *restrict buf)
{
+#ifdef SYS_stat
return syscall(SYS_stat, path, buf);
+#else
+ return syscall(SYS_fstatat, AT_FDCWD, path, buf, 0);
+#endif
}
LFS64(stat);
diff --git a/src/stdio/rename.c b/src/stdio/rename.c
index 97f1453..04c90c0 100644
--- a/src/stdio/rename.c
+++ b/src/stdio/rename.c
@@ -1,7 +1,12 @@
#include <stdio.h>
+#include <fcntl.h>
#include "syscall.h"
int rename(const char *old, const char *new)
{
+#ifdef SYS_rename
return syscall(SYS_rename, old, new);
+#else
+ return syscall(SYS_renameat, AT_FDCWD, old, AT_FDCWD, new);
+#endif
}
diff --git a/src/unistd/access.c b/src/unistd/access.c
index e7ce73a..d6eed68 100644
--- a/src/unistd/access.c
+++ b/src/unistd/access.c
@@ -1,7 +1,12 @@
#include <unistd.h>
+#include <fcntl.h>
#include "syscall.h"
int access(const char *filename, int amode)
{
+#ifdef SYS_access
return syscall(SYS_access, filename, amode);
+#else
+ return syscall(SYS_faccessat, AT_FDCWD, filename, amode, 0);
+#endif
}
diff --git a/src/unistd/chown.c b/src/unistd/chown.c
index 95f6f61..14b0325 100644
--- a/src/unistd/chown.c
+++ b/src/unistd/chown.c
@@ -1,7 +1,12 @@
#include <unistd.h>
+#include <fcntl.h>
#include "syscall.h"
int chown(const char *path, uid_t uid, gid_t gid)
{
+#ifdef SYS_chown
return syscall(SYS_chown, path, uid, gid);
+#else
+ return syscall(SYS_fchownat, AT_FDCWD, path, uid, gid, 0);
+#endif
}
diff --git a/src/unistd/dup2.c b/src/unistd/dup2.c
index 87a0d44..7bfcaf2 100644
--- a/src/unistd/dup2.c
+++ b/src/unistd/dup2.c
@@ -5,6 +5,15 @@
int dup2(int old, int new)
{
int r;
+#ifdef SYS_dup2
while ((r=__syscall(SYS_dup2, old, new))==-EBUSY);
+#else
+ if (old==new) {
+ if (__syscall(SYS_fcntl, old, F_GETFD) < 0)
+ return __syscall_ret(-EBADF);
+ return 0;
+ }
+ while ((r=__syscall(SYS_dup3, old, new, 0))==-EBUSY);
+#endif
return __syscall_ret(r);
}
diff --git a/src/unistd/getpgrp.c b/src/unistd/getpgrp.c
index 433f42e..2c8aae6 100644
--- a/src/unistd/getpgrp.c
+++ b/src/unistd/getpgrp.c
@@ -1,7 +1,16 @@
#include <unistd.h>
#include "syscall.h"
+#include "pthread_impl.h"
pid_t getpgrp(void)
{
+#ifdef SYS_getpgrp
return __syscall(SYS_getpgrp);
+#else
+ sigset_t set;
+ __block_app_sigs(&set);
+ pid_t ret = __syscall(SYS_getpgid, __syscall(SYS_getpid));
+ __restore_sigs(&set);
+ return ret;
+#endif
}
diff --git a/src/unistd/lchown.c b/src/unistd/lchown.c
index de871ae..ccd5ee0 100644
--- a/src/unistd/lchown.c
+++ b/src/unistd/lchown.c
@@ -1,7 +1,12 @@
#include <unistd.h>
+#include <fcntl.h>
#include "syscall.h"
int lchown(const char *path, uid_t uid, gid_t gid)
{
+#ifdef SYS_lchown
return syscall(SYS_lchown, path, uid, gid);
+#else
+ return syscall(SYS_fchownat, AT_FDCWD, path, uid, gid, AT_SYMLINK_NOFOLLOW);
+#endif
}
diff --git a/src/unistd/link.c b/src/unistd/link.c
index 20193f2..feec18e 100644
--- a/src/unistd/link.c
+++ b/src/unistd/link.c
@@ -1,7 +1,12 @@
#include <unistd.h>
+#include <fcntl.h>
#include "syscall.h"
int link(const char *existing, const char *new)
{
+#ifdef SYS_link
return syscall(SYS_link, existing, new);
+#else
+ return syscall(SYS_linkat, AT_FDCWD, existing, AT_FDCWD, new, 0);
+#endif
}
diff --git a/src/unistd/pause.c b/src/unistd/pause.c
index f7ed17d..50bf3b1 100644
--- a/src/unistd/pause.c
+++ b/src/unistd/pause.c
@@ -4,5 +4,11 @@
int pause(void)
{
+#ifdef SYS_pause
return syscall_cp(SYS_pause);
+#else
+ sigset_t mask;
+ __syscall(SYS_rt_sigprocmask, SIG_BLOCK, 0, &mask, _NSIG/8);
+ return syscall_cp(SYS_rt_sigsuspend, &mask, _NSIG/8);
+#endif
}
diff --git a/src/unistd/pipe.c b/src/unistd/pipe.c
index 36c6f13..d07b8d2 100644
--- a/src/unistd/pipe.c
+++ b/src/unistd/pipe.c
@@ -3,5 +3,9 @@
int pipe(int fd[2])
{
+#ifdef SYS_pipe
return syscall(SYS_pipe, fd);
+#else
+ return syscall(SYS_pipe2, fd, 0);
+#endif
}
diff --git a/src/unistd/readlink.c b/src/unistd/readlink.c
index ec291e3..a152d52 100644
--- a/src/unistd/readlink.c
+++ b/src/unistd/readlink.c
@@ -1,7 +1,12 @@
#include <unistd.h>
+#include <fcntl.h>
#include "syscall.h"
ssize_t readlink(const char *restrict path, char *restrict buf, size_t bufsize)
{
+#ifdef SYS_readlink
return syscall(SYS_readlink, path, buf, bufsize);
+#else
+ return syscall(SYS_readlinkat, AT_FDCWD, path, buf, bufsize);
+#endif
}
diff --git a/src/unistd/rmdir.c b/src/unistd/rmdir.c
index dfe1605..6825ffc 100644
--- a/src/unistd/rmdir.c
+++ b/src/unistd/rmdir.c
@@ -1,7 +1,12 @@
#include <unistd.h>
+#include <fcntl.h>
#include "syscall.h"
int rmdir(const char *path)
{
+#ifdef SYS_rmdir
return syscall(SYS_rmdir, path);
+#else
+ return syscall(SYS_unlinkat, AT_FDCWD, path, AT_REMOVEDIR);
+#endif
}
diff --git a/src/unistd/symlink.c b/src/unistd/symlink.c
index 5902d45..0973d78 100644
--- a/src/unistd/symlink.c
+++ b/src/unistd/symlink.c
@@ -1,7 +1,12 @@
#include <unistd.h>
+#include <fcntl.h>
#include "syscall.h"
int symlink(const char *existing, const char *new)
{
+#ifdef SYS_symlink
return syscall(SYS_symlink, existing, new);
+#else
+ return syscall(SYS_symlinkat, existing, AT_FDCWD, new);
+#endif
}
diff --git a/src/unistd/unlink.c b/src/unistd/unlink.c
index bdb37be..c40c28d 100644
--- a/src/unistd/unlink.c
+++ b/src/unistd/unlink.c
@@ -1,7 +1,12 @@
#include <unistd.h>
+#include <fcntl.h>
#include "syscall.h"
int unlink(const char *path)
{
+#ifdef SYS_unlink
return syscall(SYS_unlink, path);
+#else
+ return syscall(SYS_unlinkat, AT_FDCWD, path, 0);
+#endif
}
next reply other threads:[~2014-05-25 5:42 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-05-25 5:42 Rich Felker [this message]
2014-05-25 9:52 ` Szabolcs Nagy
2014-05-25 9:57 ` Justin Cormack
2014-05-25 11:45 ` Rich Felker
2014-05-26 4:28 ` Rich Felker
2014-05-26 18:40 ` [UGLY PATCH v2] " Rich Felker
2014-05-26 21:13 ` Szabolcs Nagy
2014-05-26 21:54 ` Rich Felker
2014-05-26 22:39 ` Szabolcs Nagy
2014-05-26 22:46 ` Rich Felker
2014-05-27 5:26 ` [UGLY PATCH v3] " Rich Felker
2014-05-27 11:29 ` Szabolcs Nagy
2014-05-27 19:01 ` Rich Felker
2014-05-29 21:46 ` Rich Felker
2014-05-29 23:04 ` Rich Felker
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140525054237.GA18085@brightrain.aerifal.cx \
--to=dalias@libc.org \
--cc=musl@lists.openwall.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/musl/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).