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:
Stefan Kalkowski
2015-09-03 14:55:05 +02:00
committed by Christian Helmuth
parent 6cdb823187
commit ed52d5a211
786 changed files with 1240 additions and 1202 deletions

View 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_ */

View 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

View 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

View 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

View 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

View 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

View 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

View 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