mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-14 05:08:19 +00:00
Introduce 'spec' subdirectories to outline aspects
Instead of holding SPEC-variable dependent files and directories inline within the repository structure, move them into 'spec' subdirectories at the corresponding levels, e.g.: repos/base/include/spec repos/base/mk/spec repos/base/lib/mk/spec repos/base/src/core/spec ... Moreover, this commit removes the 'platform' directories. That term was used in an overloaded sense. All SPEC-relative 'platform' directories are now named 'spec'. Other files, like for instance those related to the kernel/architecture specific startup library, where moved from 'platform' directories to explicit, more meaningful places like e.g.: 'src/lib/startup'. Fix #1673
This commit is contained in:
committed by
Christian Helmuth
parent
6cdb823187
commit
ed52d5a211
395
repos/base-linux/src/lib/syscall/linux_syscalls.h
Normal file
395
repos/base-linux/src/lib/syscall/linux_syscalls.h
Normal file
@ -0,0 +1,395 @@
|
||||
/*
|
||||
* \brief Linux system-call bindings
|
||||
* \author Norman Feske
|
||||
* \date 2008-10-22
|
||||
*
|
||||
* This file is meant to be internally used by the framework. It is not public
|
||||
* interface.
|
||||
*
|
||||
* From within the framework libraries, we have to use the Linux syscall
|
||||
* interface directly rather than relying on convenient libc functions to be
|
||||
* able to link this part of the framework to a custom libc. Otherwise, we
|
||||
* would end up with very nasty cyclic dependencies when using framework
|
||||
* functions such as IPC from the libc back end.
|
||||
*
|
||||
* The Linux syscall interface looks different for 32bit and 64bit system, in
|
||||
* particular regarding the socket interface. On 32bit systems, all socket
|
||||
* operations are invoked via the 'socketcall' syscall. On 64bit systems, the
|
||||
* different socket functions have distinct syscalls.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2008-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _LIB__SYSCALL__LINUX_SYSCALLS_H_
|
||||
#define _LIB__SYSCALL__LINUX_SYSCALLS_H_
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE 1 /* needed to enable the definition of 'stat64' */
|
||||
#endif
|
||||
|
||||
/* Linux includes */
|
||||
#include <linux/futex.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <sched.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/string.h>
|
||||
#include <base/printf.h>
|
||||
#include <base/snprintf.h>
|
||||
|
||||
|
||||
/***********************************
|
||||
** Low-level debugging utilities **
|
||||
***********************************/
|
||||
|
||||
extern "C" void wait_for_continue(void);
|
||||
extern "C" int raw_write_str(const char *str);
|
||||
|
||||
#define PRAW(fmt, ...) \
|
||||
do { \
|
||||
char str[128]; \
|
||||
Genode::snprintf(str, sizeof(str), \
|
||||
ESC_ERR fmt ESC_END "\n", ##__VA_ARGS__); \
|
||||
raw_write_str(str); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/*********************************************************
|
||||
** System-call bindings implemented in syscall library **
|
||||
*********************************************************/
|
||||
|
||||
extern "C" long lx_syscall(int number, ...);
|
||||
extern "C" int lx_clone(int (*fn)(void *), void *child_stack,
|
||||
int flags, void *arg);
|
||||
|
||||
|
||||
/*****************************************
|
||||
** General syscalls used by base-linux **
|
||||
*****************************************/
|
||||
|
||||
inline int lx_write(int fd, const void *buf, Genode::size_t count)
|
||||
{
|
||||
return lx_syscall(SYS_write, fd, buf, count);
|
||||
}
|
||||
|
||||
|
||||
inline int lx_close(int fd)
|
||||
{
|
||||
return lx_syscall(SYS_close, fd);
|
||||
}
|
||||
|
||||
|
||||
inline int lx_dup2(int fd, int to)
|
||||
{
|
||||
return lx_syscall(SYS_dup2, fd, to);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************
|
||||
** Functions used by the IPC framework **
|
||||
*****************************************/
|
||||
|
||||
#include <linux/net.h>
|
||||
|
||||
#ifdef SYS_socketcall
|
||||
|
||||
inline int lx_socketcall(int call, long *args)
|
||||
{
|
||||
int res = lx_syscall(SYS_socketcall, call, args);
|
||||
return res;
|
||||
}
|
||||
|
||||
inline int lx_socketpair(int domain, int type, int protocol, int sd[2])
|
||||
{
|
||||
long args[4] = { domain, type, protocol, (long)sd };
|
||||
return lx_socketcall(SYS_SOCKETPAIR, args);
|
||||
}
|
||||
|
||||
|
||||
inline int lx_sendmsg(int sockfd, const struct msghdr *msg, int flags)
|
||||
{
|
||||
long args[3] = { sockfd, (long)msg, flags };
|
||||
return lx_socketcall(SYS_SENDMSG, args);
|
||||
}
|
||||
|
||||
|
||||
inline int lx_recvmsg(int sockfd, struct msghdr *msg, int flags)
|
||||
{
|
||||
long args[3] = { sockfd, (long)msg, flags };
|
||||
return lx_socketcall(SYS_RECVMSG, args);
|
||||
}
|
||||
|
||||
|
||||
inline int lx_getpeername(int sockfd, struct sockaddr *name, socklen_t *namelen)
|
||||
{
|
||||
long args[3] = { sockfd, (long)name, (long)namelen };
|
||||
return lx_socketcall(SYS_GETPEERNAME, args);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
inline int lx_socketpair(int domain, int type, int protocol, int sd[2])
|
||||
{
|
||||
return lx_syscall(SYS_socketpair, domain, type, protocol, (unsigned long)sd);
|
||||
}
|
||||
|
||||
|
||||
inline int lx_sendmsg(int sockfd, const struct msghdr *msg, int flags)
|
||||
{
|
||||
return lx_syscall(SYS_sendmsg, sockfd, msg, flags);
|
||||
}
|
||||
|
||||
|
||||
inline int lx_recvmsg(int sockfd, struct msghdr *msg, int flags)
|
||||
{
|
||||
return lx_syscall(SYS_recvmsg, sockfd, msg, flags);
|
||||
}
|
||||
|
||||
|
||||
inline int lx_getpeername(int sockfd, struct sockaddr *name, socklen_t *namelen)
|
||||
{
|
||||
return lx_syscall(SYS_getpeername, sockfd, name, namelen);
|
||||
}
|
||||
|
||||
/* TODO add missing socket system calls */
|
||||
|
||||
#endif /* SYS_socketcall */
|
||||
|
||||
|
||||
/*******************************************
|
||||
** Functions used by the process library **
|
||||
*******************************************/
|
||||
|
||||
inline void lx_exit(int status)
|
||||
{
|
||||
lx_syscall(SYS_exit, status);
|
||||
}
|
||||
|
||||
|
||||
inline void lx_exit_group(int status)
|
||||
{
|
||||
lx_syscall(SYS_exit_group, status);
|
||||
}
|
||||
|
||||
|
||||
/************************************************************
|
||||
** Functions used by the env library and local rm session **
|
||||
************************************************************/
|
||||
|
||||
/* O_CLOEXEC is a GNU extension so we provide it here */
|
||||
enum { LX_O_CLOEXEC = 02000000 };
|
||||
|
||||
inline void *lx_mmap(void *start, Genode::size_t length, int prot, int flags,
|
||||
int fd, off_t offset)
|
||||
{
|
||||
#ifdef _LP64
|
||||
return (void *)lx_syscall(SYS_mmap, start, length, prot, flags, fd, offset);
|
||||
#else
|
||||
return (void *)lx_syscall(SYS_mmap2, start, length, prot, flags, fd, offset/4096);
|
||||
#endif /* _LP64 */
|
||||
}
|
||||
|
||||
|
||||
inline int lx_munmap(void *addr, size_t length)
|
||||
{
|
||||
return lx_syscall(SYS_munmap, addr, length);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
** Functions used by thread lib and core's cancel-blocking mechanism **
|
||||
***********************************************************************/
|
||||
|
||||
enum {
|
||||
LX_SIGINT = 2, /* used by core to catch Control-C */
|
||||
LX_SIGILL = 4, /* exception: illegal instruction */
|
||||
LX_SIGBUS = 7, /* exception: bus error, i.e., bad memory access */
|
||||
LX_SIGFPE = 8, /* exception: floating point */
|
||||
LX_SIGUSR1 = 10, /* used for cancel-blocking mechanism */
|
||||
LX_SIGSEGV = 11, /* exception: segmentation violation */
|
||||
LX_SIGCHLD = 17, /* child process changed state, i.e., terminated */
|
||||
LX_SIGCANCEL = 32, /* accoring to glibc, this equals SIGRTMIN,
|
||||
used for killing threads */
|
||||
};
|
||||
|
||||
|
||||
struct kernel_sigaction
|
||||
{
|
||||
void (*handler)(int);
|
||||
unsigned long flags;
|
||||
void (*restorer)(void);
|
||||
sigset_t mask;
|
||||
};
|
||||
|
||||
|
||||
inline int lx_sigemptyset(sigset_t *set)
|
||||
{
|
||||
if (set == 0)
|
||||
return -1;
|
||||
Genode::memset(set, 0, sizeof(sigset_t));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef _LP64
|
||||
extern "C" void lx_restore_rt (void);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Simplified binding for sigaction system call
|
||||
*/
|
||||
inline int lx_sigaction(int signum, void (*handler)(int))
|
||||
{
|
||||
struct kernel_sigaction act;
|
||||
act.handler = handler;
|
||||
|
||||
#ifdef _LP64
|
||||
/*
|
||||
* The SA_RESTORER flag is not officially documented, but used internally
|
||||
* by the glibc implementation of sigaction(). Without specifying this flag
|
||||
* tgkill() does not work on x86_64. The restorer function gets called
|
||||
* when leaving the signal handler and it should call the rt_sigreturn syscall.
|
||||
*/
|
||||
enum { SA_RESTORER = 0x04000000 };
|
||||
act.flags = SA_RESTORER;
|
||||
act.restorer = lx_restore_rt;
|
||||
#else
|
||||
act.flags = 0;
|
||||
act.restorer = 0;
|
||||
#endif
|
||||
lx_sigemptyset(&act.mask);
|
||||
|
||||
return lx_syscall(SYS_rt_sigaction, signum, &act, 0UL, _NSIG/8);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Send signal to thread
|
||||
*
|
||||
* This function is used by core to cancel blocking operations of
|
||||
* threads, and by the thread library to kill threads.
|
||||
*/
|
||||
inline int lx_tgkill(int pid, int tid, int signal)
|
||||
{
|
||||
return lx_syscall(SYS_tgkill, pid, tid, signal);
|
||||
}
|
||||
|
||||
|
||||
inline int lx_create_thread(void (*entry)(), void *stack, void *arg)
|
||||
{
|
||||
int flags = CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND
|
||||
| CLONE_THREAD | CLONE_SYSVSEM;
|
||||
|
||||
/*
|
||||
* The syscall binding for clone does not exist in the FreeBSD libc, which
|
||||
* we are using as libc for Genode. In glibc, clone is implemented as a
|
||||
* assembler binding without external libc references. Hence, we are safe
|
||||
* to rely on the glibc version of 'clone' here.
|
||||
*/
|
||||
return lx_clone((int (*)(void *))entry, stack, flags, arg);
|
||||
}
|
||||
|
||||
|
||||
inline pid_t lx_getpid() { return lx_syscall(SYS_getpid); }
|
||||
inline pid_t lx_gettid() { return lx_syscall(SYS_gettid); }
|
||||
inline uid_t lx_getuid() { return lx_syscall(SYS_getuid); }
|
||||
|
||||
|
||||
/************************************
|
||||
** Functions used by lock library **
|
||||
************************************/
|
||||
|
||||
struct timespec;
|
||||
|
||||
inline int lx_nanosleep(const struct timespec *req, struct timespec *rem)
|
||||
{
|
||||
return lx_syscall(SYS_nanosleep, req, rem);
|
||||
}
|
||||
|
||||
enum {
|
||||
LX_FUTEX_WAIT = FUTEX_WAIT,
|
||||
LX_FUTEX_WAKE = FUTEX_WAKE,
|
||||
};
|
||||
|
||||
inline int lx_futex(const int *uaddr, int op, int val)
|
||||
{
|
||||
return lx_syscall(SYS_futex, uaddr, op, val, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Signal set corrsponding to glibc's 'sigset_t'
|
||||
*/
|
||||
class Lx_sigset
|
||||
{
|
||||
unsigned long int _value[_SIGSET_NWORDS];
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Lx_sigset() { }
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param signum set specified entry of sigset
|
||||
*/
|
||||
Lx_sigset(int signum)
|
||||
{
|
||||
|
||||
for (unsigned i = 0; i < _SIGSET_NWORDS; i++)
|
||||
_value[i] = 0;
|
||||
|
||||
/*
|
||||
* Both '__sigword' and '__sigmask' are macros, defined in the
|
||||
* glibc header file 'bits/sigset.h' and not external functions.
|
||||
* Therefore we can use them here without getting into conflicts
|
||||
* with the linkage of another libc.
|
||||
*/
|
||||
_value[__sigword(signum)] = __sigmask(signum);
|
||||
}
|
||||
|
||||
bool is_set(int signum) {
|
||||
return _value[__sigword(signum)] && __sigmask(signum); }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Check if signal is pending
|
||||
*
|
||||
* \return true if signal is pending
|
||||
*/
|
||||
inline bool lx_sigpending(int signum)
|
||||
{
|
||||
Lx_sigset sigset;
|
||||
lx_syscall(SYS_rt_sigpending, &sigset, _NSIG/8);
|
||||
return sigset.is_set(signum);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set signal mask state
|
||||
*
|
||||
* \param signum signal to mask or unmask
|
||||
* \param state mask state for the signal,
|
||||
* true enables the signal,
|
||||
* false blocks the signal
|
||||
*/
|
||||
inline bool lx_sigsetmask(int signum, bool state)
|
||||
{
|
||||
Lx_sigset old_sigmask, sigset(signum);
|
||||
lx_syscall(SYS_rt_sigprocmask, state ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old_sigmask, _NSIG/8);
|
||||
return old_sigmask.is_set(signum);
|
||||
}
|
||||
|
||||
|
||||
#endif /* _LIB__SYSCALL__LINUX_SYSCALLS_H_ */
|
94
repos/base-linux/src/lib/syscall/spec/arm/lx_clone.S
Normal file
94
repos/base-linux/src/lib/syscall/spec/arm/lx_clone.S
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* \brief Linux clone() binding
|
||||
* \author Christian Prochaska
|
||||
* \date 2012-05-05
|
||||
*
|
||||
* based on eglibc-2.11.3/ports/sysdeps/unix/sysv/linux/arm/clone.S
|
||||
*/
|
||||
|
||||
#define SYS_clone 120
|
||||
#define SYS_exit 1
|
||||
#define SYS_getpid 20
|
||||
|
||||
#define __ARM_EABI__ 1
|
||||
|
||||
#define CLONE_VM 0x00000100
|
||||
#define CLONE_THREAD 0x00010000
|
||||
|
||||
.text
|
||||
.globl lx_clone
|
||||
.type lx_clone, #function
|
||||
lx_clone:
|
||||
|
||||
@ insert the args onto the new stack
|
||||
str r3, [r1, #-4]!
|
||||
str r0, [r1, #-4]!
|
||||
|
||||
@ do the system call
|
||||
@ get flags
|
||||
mov r0, r2
|
||||
#ifdef RESET_PID
|
||||
mov ip, r2
|
||||
#endif
|
||||
@ new sp is already in r1
|
||||
#ifdef __ARM_EABI__
|
||||
stmfd sp!, {r4, r7}
|
||||
#else
|
||||
str r4, [sp, #-8]!
|
||||
#endif
|
||||
ldr r2, [sp, #8]
|
||||
ldr r3, [sp, #12]
|
||||
ldr r4, [sp, #16]
|
||||
#ifdef __ARM_EABI__
|
||||
ldr r7, =SYS_clone
|
||||
swi 0x0
|
||||
#else
|
||||
swi SYS_clone
|
||||
#endif
|
||||
cmp r0, #0
|
||||
beq 1f
|
||||
#ifdef __ARM_EABI__
|
||||
ldmfd sp!, {r4, r7}
|
||||
#else
|
||||
ldr r4, [sp], #8
|
||||
#endif
|
||||
#blt PLTJMP(C_SYMBOL_NAME(__syscall_error))
|
||||
bx lr
|
||||
|
||||
1:
|
||||
#ifdef RESET_PID
|
||||
tst ip, #CLONE_THREAD
|
||||
bne 3f
|
||||
mov r0, #0xffff0fff
|
||||
mov lr, pc
|
||||
sub pc, r0, #31
|
||||
mov r1, r0
|
||||
tst ip, #CLONE_VM
|
||||
movne r0, #-1
|
||||
#ifdef __ARM_EABI__
|
||||
ldr r7, =SYS_getpid
|
||||
swieq 0x0
|
||||
#else
|
||||
swieq SYS_getpid
|
||||
#endif
|
||||
str r0, [r1, #PID_OFFSET]
|
||||
str r0, [r1, #TID_OFFSET]
|
||||
3:
|
||||
#endif
|
||||
@ pick the function arg and call address off the stack and execute
|
||||
ldr r0, [sp, #4]
|
||||
#if defined(__ARM_ARCH_4T__) && defined(__THUMB_INTERWORK__)
|
||||
ldr ip, [sp], #8
|
||||
mov lr, pc
|
||||
bx ip
|
||||
#else
|
||||
mov lr, pc
|
||||
ldr pc, [sp], #8
|
||||
#endif
|
||||
|
||||
@ and we are done, passing the return value through r0
|
||||
ldr r7, =SYS_exit
|
||||
swi 0x0
|
||||
|
||||
/* tell the linker that this code does not need an executable stack */
|
||||
.section .note.GNU-stack, "", %progbits
|
29
repos/base-linux/src/lib/syscall/spec/arm/lx_syscall.S
Normal file
29
repos/base-linux/src/lib/syscall/spec/arm/lx_syscall.S
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* \brief Linux syscall() binding
|
||||
* \author Christian Prochaska
|
||||
* \date 2012-05-05
|
||||
*
|
||||
* based on eglibc-2.11.3/ports/sysdeps/unix/sysv/linux/arm/syscall.S
|
||||
*
|
||||
* error case:
|
||||
* glibc's syscall() function returns -1 and sets errno
|
||||
* lx_syscall() returns -errno
|
||||
*/
|
||||
|
||||
.text
|
||||
.globl lx_syscall
|
||||
.type lx_syscall, #function
|
||||
lx_syscall:
|
||||
mov ip, sp
|
||||
stmfd sp!, {r4, r5, r6, r7}
|
||||
mov r7, r0
|
||||
mov r0, r1
|
||||
mov r1, r2
|
||||
mov r2, r3
|
||||
ldmfd ip, {r3, r4, r5, r6}
|
||||
swi 0x0
|
||||
ldmfd sp!, {r4, r5, r6, r7}
|
||||
bx lr
|
||||
|
||||
/* tell the linker that this code does not need an executable stack */
|
||||
.section .note.GNU-stack, "", %progbits
|
108
repos/base-linux/src/lib/syscall/spec/x86_32/lx_clone.S
Normal file
108
repos/base-linux/src/lib/syscall/spec/x86_32/lx_clone.S
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* \brief Linux clone() binding
|
||||
* \author Christian Prochaska
|
||||
* \date 2009-07-14
|
||||
*
|
||||
* based on glibc-2.9/sysdeps/unix/sysv/linux/i386/clone.S
|
||||
*/
|
||||
|
||||
|
||||
#define L(name) name
|
||||
|
||||
#define ENTER_KERNEL int $0x80
|
||||
#define SYS_clone 120
|
||||
#define SYS_exit 1
|
||||
|
||||
#define LINKAGE 4
|
||||
#define PTR_SIZE 4
|
||||
|
||||
#define PARMS LINKAGE /* no space for saved regs */
|
||||
#define FUNC PARMS
|
||||
#define STACK FUNC+4
|
||||
#define FLAGS STACK+PTR_SIZE
|
||||
#define ARG FLAGS+4
|
||||
#define PTID ARG+PTR_SIZE
|
||||
#define TLS PTID+PTR_SIZE
|
||||
#define CTID TLS+PTR_SIZE
|
||||
|
||||
.text
|
||||
.globl lx_clone
|
||||
.type lx_clone, @function
|
||||
lx_clone:
|
||||
.cfi_startproc
|
||||
|
||||
/* Insert the argument onto the new stack. Make sure the new
|
||||
thread is started with an alignment of (mod 16). */
|
||||
movl STACK(%esp),%ecx
|
||||
andl $0xfffffff0, %ecx
|
||||
subl $28,%ecx
|
||||
movl ARG(%esp),%eax /* no negative argument counts */
|
||||
movl %eax,12(%ecx)
|
||||
|
||||
/* Save the function pointer as the zeroth argument.
|
||||
It will be popped off in the child in the ebx frobbing below. */
|
||||
movl FUNC(%esp),%eax
|
||||
movl %eax,8(%ecx)
|
||||
/* Don't leak any information. */
|
||||
movl $0,4(%ecx)
|
||||
movl $0,(%ecx)
|
||||
|
||||
/* Do the system call */
|
||||
pushl %ebx
|
||||
.cfi_adjust_cfa_offset (4)
|
||||
pushl %esi
|
||||
.cfi_adjust_cfa_offset (4)
|
||||
pushl %edi
|
||||
.cfi_adjust_cfa_offset (4)
|
||||
|
||||
movl TLS+12(%esp),%esi
|
||||
.cfi_rel_offset %esi, 4
|
||||
movl PTID+12(%esp),%edx
|
||||
movl FLAGS+12(%esp),%ebx
|
||||
.cfi_rel_offset %ebx, 8
|
||||
movl CTID+12(%esp),%edi
|
||||
.cfi_rel_offset %edi, 0
|
||||
movl $SYS_clone,%eax
|
||||
|
||||
/* End FDE now, because in the child the unwind info will be
|
||||
wrong. */
|
||||
.cfi_endproc
|
||||
|
||||
ENTER_KERNEL
|
||||
popl %edi
|
||||
popl %esi
|
||||
popl %ebx
|
||||
|
||||
test %eax,%eax
|
||||
jz L(thread_start)
|
||||
|
||||
L(pseudo_end):
|
||||
ret
|
||||
|
||||
L(thread_start):
|
||||
.cfi_startproc;
|
||||
/* Clearing frame pointer is insufficient, use CFI. */
|
||||
.cfi_undefined %eip;
|
||||
xorl %ebp,%ebp /* terminate the stack frame */
|
||||
call *%ebx
|
||||
#ifdef PIC
|
||||
call L(here)
|
||||
L(here):
|
||||
popl %ebx
|
||||
addl $_GLOBAL_OFFSET_TABLE_+[.-L(here)], %ebx
|
||||
#endif
|
||||
movl %eax, %ebx
|
||||
movl $SYS_exit, %eax
|
||||
ENTER_KERNEL
|
||||
|
||||
.cfi_endproc;
|
||||
|
||||
.cfi_startproc
|
||||
.cfi_endproc
|
||||
|
||||
/*
|
||||
* Allow stacks to be mapped executable (needed because Genode does not
|
||||
* offer an API to handle non-execute mappings yet).
|
||||
*/
|
||||
.section .note.GNU-stack, "", @progbits
|
||||
|
83
repos/base-linux/src/lib/syscall/spec/x86_32/lx_syscall.S
Normal file
83
repos/base-linux/src/lib/syscall/spec/x86_32/lx_syscall.S
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* \brief Linux syscall() binding
|
||||
* \author Christian Prochaska
|
||||
* \date 2009-07-14
|
||||
*
|
||||
* based on glibc-2.9/sysdeps/unix/sysv/linux/i386/syscall.S
|
||||
*
|
||||
* error case:
|
||||
* glibc's syscall() function returns -1 and sets errno
|
||||
* lx_syscall() returns -errno
|
||||
*/
|
||||
|
||||
|
||||
#define L(name) name
|
||||
|
||||
#define ENTER_KERNEL int $0x80
|
||||
|
||||
.text
|
||||
.globl lx_syscall
|
||||
.type lx_syscall, @function
|
||||
lx_syscall:
|
||||
.cfi_startproc
|
||||
/* PUSHARGS_6*/ /* Save register contents. */
|
||||
/* PUSHARGS_6 begin */
|
||||
pushl %ebp;
|
||||
.cfi_adjust_cfa_offset 4;
|
||||
.cfi_rel_offset %ebp, 0;
|
||||
L(PUSHBP1):
|
||||
pushl %edi;
|
||||
.cfi_adjust_cfa_offset 4;
|
||||
.cfi_rel_offset %edi, 0;
|
||||
L(PUSHDI1):
|
||||
pushl %esi;
|
||||
.cfi_adjust_cfa_offset 4;
|
||||
.cfi_rel_offset %esi, 0;
|
||||
L(PUSHSI1):
|
||||
pushl %ebx;
|
||||
.cfi_adjust_cfa_offset 4;
|
||||
.cfi_rel_offset %ebx, 0;
|
||||
L(PUSHBX1):
|
||||
/* PUSHARGS_6 end */
|
||||
|
||||
/*_DOARGS_6(44)*/ /* Load arguments. */
|
||||
/*_DOARGS_6(44) begin*/
|
||||
movl 44(%esp), %ebp;
|
||||
movl 40(%esp), %edi;
|
||||
movl 36(%esp), %esi;
|
||||
movl 32(%esp), %edx;
|
||||
movl 28(%esp), %ecx;
|
||||
movl 24(%esp), %ebx;
|
||||
/*_DOARGS_6(44) end*/
|
||||
movl 20(%esp), %eax /* Load syscall number into %eax. */
|
||||
ENTER_KERNEL /* Do the system call. */
|
||||
/* POPARGS_6*/ /* Restore register contents. */
|
||||
/* POPARGS_6 begin */
|
||||
popl %ebx;
|
||||
.cfi_adjust_cfa_offset -4;
|
||||
.cfi_restore %ebx;
|
||||
L(POPBX1):
|
||||
popl %esi;
|
||||
.cfi_adjust_cfa_offset -4;
|
||||
.cfi_restore %esi;
|
||||
L(POPSI1):
|
||||
popl %edi;
|
||||
.cfi_adjust_cfa_offset -4;
|
||||
.cfi_restore %edi;
|
||||
L(POPDI1):
|
||||
popl %ebp;
|
||||
.cfi_adjust_cfa_offset -4;
|
||||
.cfi_restore %ebp;
|
||||
L(POPBP1):
|
||||
/* POPARGS_6 end */
|
||||
L(pseudo_end):
|
||||
ret /* Return to caller. */
|
||||
|
||||
.cfi_endproc
|
||||
|
||||
/*
|
||||
* Allow stacks to be mapped executable (needed because Genode does not
|
||||
* offer an API to handle non-execute mappings yet).
|
||||
*/
|
||||
.section .note.GNU-stack, "", @progbits
|
||||
|
74
repos/base-linux/src/lib/syscall/spec/x86_64/lx_clone.S
Normal file
74
repos/base-linux/src/lib/syscall/spec/x86_64/lx_clone.S
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* \brief Linux clone() binding
|
||||
* \author Christian Prochaska
|
||||
* \date 2009-07-14
|
||||
*
|
||||
* based on glibc-2.9/sysdeps/unix/sysv/linux/x86_64/clone.S
|
||||
*/
|
||||
|
||||
#define L(name) name
|
||||
|
||||
#define SYS_clone 56
|
||||
#define SYS_exit 60
|
||||
|
||||
.text
|
||||
.globl lx_clone
|
||||
.type lx_clone, @function
|
||||
lx_clone:
|
||||
.cfi_startproc
|
||||
|
||||
/* Align the new stack pointer to 16 bytes. */
|
||||
andq $0xfffffffffffffff0, %rsi
|
||||
|
||||
/* Insert the argument onto the new stack. */
|
||||
subq $16,%rsi
|
||||
movq %rcx,8(%rsi)
|
||||
|
||||
/* Save the function pointer. It will be popped off in the
|
||||
child in the ebx frobbing below. */
|
||||
movq %rdi,0(%rsi)
|
||||
|
||||
/* Do the system call. */
|
||||
movq %rdx, %rdi
|
||||
movq %r8, %rdx
|
||||
movq %r9, %r8
|
||||
movq 8(%rsp), %r10
|
||||
movl $SYS_clone,%eax
|
||||
|
||||
/* End FDE now, because in the child the unwind info will be
|
||||
wrong. */
|
||||
.cfi_endproc
|
||||
syscall
|
||||
|
||||
testq %rax,%rax
|
||||
jz L(thread_start)
|
||||
|
||||
L(pseudo_end):
|
||||
/* parent returns */
|
||||
ret
|
||||
|
||||
L(thread_start):
|
||||
.cfi_startproc
|
||||
/* Clearing frame pointer is insufficient, use CFI. */
|
||||
.cfi_undefined (%rip);
|
||||
|
||||
/* Clear the frame pointer. The ABI suggests this be done, to mark
|
||||
the outermost frame obviously. */
|
||||
xorq %rbp, %rbp
|
||||
|
||||
/* Set up arguments for the function call. */
|
||||
popq %rax /* Function to call. */
|
||||
popq %rdi /* Argument. */
|
||||
call *%rax
|
||||
/* Call exit with return value from function call. */
|
||||
movq %rax, %rdi
|
||||
movq $SYS_exit, %rax
|
||||
syscall
|
||||
.cfi_endproc
|
||||
|
||||
/*
|
||||
* Allow stacks to be mapped executable (needed because Genode does not
|
||||
* offer an API to handle non-executable mappings yet).
|
||||
*/
|
||||
.section .note.GNU-stack, "", @progbits
|
||||
|
23
repos/base-linux/src/lib/syscall/spec/x86_64/lx_restore_rt.S
Normal file
23
repos/base-linux/src/lib/syscall/spec/x86_64/lx_restore_rt.S
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* \brief Linux signal handler restorer function
|
||||
* \author Christian Prochaska
|
||||
* \date 2009-07-14
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#define SYS_rt_sigreturn 15
|
||||
|
||||
.text
|
||||
.globl lx_restore_rt
|
||||
.type lx_restore_rt, @function
|
||||
lx_restore_rt:
|
||||
movq $SYS_rt_sigreturn, %rax
|
||||
syscall
|
||||
|
||||
/*
|
||||
* Allow stacks to be mapped executable (needed because Genode does not
|
||||
* offer an API to handle non-execute mappings yet).
|
||||
*/
|
||||
.section .note.GNU-stack, "", @progbits
|
||||
|
36
repos/base-linux/src/lib/syscall/spec/x86_64/lx_syscall.S
Normal file
36
repos/base-linux/src/lib/syscall/spec/x86_64/lx_syscall.S
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* \brief Linux syscall() binding
|
||||
* \author Christian Prochaska
|
||||
* \date 2009-07-14
|
||||
*
|
||||
* based on glibc-2.9/sysdeps/unix/sysv/linux/x86_64/syscall.S
|
||||
*
|
||||
* error case:
|
||||
* glibc's syscall() function returns -1 and sets errno
|
||||
* lx_syscall() returns -errno
|
||||
*/
|
||||
|
||||
|
||||
#define L(name) name
|
||||
|
||||
.text
|
||||
.globl lx_syscall
|
||||
.type lx_syscall, @function
|
||||
lx_syscall:
|
||||
movq %rdi, %rax /* Syscall number -> rax. */
|
||||
movq %rsi, %rdi /* shift arg1 - arg5. */
|
||||
movq %rdx, %rsi
|
||||
movq %rcx, %rdx
|
||||
movq %r8, %r10
|
||||
movq %r9, %r8
|
||||
movq 8(%rsp),%r9 /* arg6 is on the stack. */
|
||||
syscall /* Do the system call. */
|
||||
L(pseudo_end):
|
||||
ret /* Return to caller. */
|
||||
|
||||
/*
|
||||
* Allow stacks to be mapped executable (needed because Genode does not
|
||||
* offer an API to handle non-execute mappings yet).
|
||||
*/
|
||||
.section .note.GNU-stack, "", @progbits
|
||||
|
Reference in New Issue
Block a user