mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
make system calls safer/clean up headers
wrap some libc functions that do system calls (terminal output) wrap read/write with syscall guard define real_read/write (next dynamic linker find for read/write) guard system calls in remaining code introduce native_internhal.h throw out some debug statements that break things clean up includes a bit declare board_init in native_internhal.h add -ldl to LINKFLAGS for cpu/syscalls
This commit is contained in:
parent
69d4f9a4bd
commit
7b9d199ec8
@ -14,7 +14,7 @@ export OBJCOPY = $(PREFIX)objcopy
|
||||
FLASHER = lpc2k_pgm
|
||||
TERM = pyterm.py
|
||||
|
||||
LINKFLAGS += -m32 -gc
|
||||
LINKFLAGS += -m32 -gc -ldl
|
||||
|
||||
ifeq ($(strip $(PORT)),)
|
||||
export PORT = /dev/ttyUSB0
|
||||
|
@ -6,6 +6,8 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <sys/select.h>
|
||||
|
||||
@ -13,21 +15,27 @@
|
||||
#include "debug.h"
|
||||
#include "board_uart0.h"
|
||||
|
||||
int _native_uart_in;
|
||||
int _native_uart_out;
|
||||
#include "native_internal.h"
|
||||
|
||||
static int _native_uart_in;
|
||||
|
||||
fd_set _native_uart_rfds;
|
||||
|
||||
inline int uart0_puts(char *astring, int length)
|
||||
int uart0_puts(char *astring, int length)
|
||||
{
|
||||
int nwritten, offset;
|
||||
|
||||
nwritten = 0;
|
||||
offset = 0;
|
||||
|
||||
_native_in_syscall = 1;
|
||||
|
||||
while ((length > 0) &&(nwritten = write(_native_uart_out, astring+offset, length-offset)) > 0) {
|
||||
while (
|
||||
(length - offset > 0) && (
|
||||
(nwritten = write(
|
||||
STDOUT_FILENO,
|
||||
astring+offset,
|
||||
length-offset)
|
||||
) > 0)
|
||||
) {
|
||||
offset += nwritten;
|
||||
}
|
||||
if (nwritten == -1) {
|
||||
@ -38,8 +46,6 @@ inline int uart0_puts(char *astring, int length)
|
||||
errx(EXIT_FAILURE, "uart0_puts: Could not write to stdout. I don't know what to do now.");
|
||||
}
|
||||
|
||||
_native_in_syscall = 0;
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
@ -53,8 +59,6 @@ void _native_handle_uart0_input()
|
||||
return;
|
||||
}
|
||||
DEBUG("_native_handle_uart0_input\n");
|
||||
_native_in_syscall = 0;
|
||||
_native_in_isr = 1;
|
||||
|
||||
nread = read(_native_uart_in, buf, sizeof(buf));
|
||||
if (nread == -1) {
|
||||
@ -66,33 +70,28 @@ void _native_handle_uart0_input()
|
||||
* with properly in #161 */
|
||||
close(_native_uart_in);
|
||||
_native_uart_in = -1;
|
||||
warnx("stdin closed");
|
||||
printf("stdin closed");
|
||||
}
|
||||
for(int pos = 0; pos < nread; pos++) {
|
||||
uart0_handle_incoming(buf[pos]);
|
||||
}
|
||||
uart0_notify_thread();
|
||||
|
||||
_native_in_isr = 0;
|
||||
thread_yield();
|
||||
}
|
||||
|
||||
int _native_set_uart_fds(void)
|
||||
{
|
||||
DEBUG("_native_set_uart_fds");
|
||||
FD_SET(_native_uart_in, &_native_rfds);
|
||||
if (_native_uart_in != -1) {
|
||||
FD_SET(_native_uart_in, &_native_rfds);
|
||||
}
|
||||
return _native_uart_in;
|
||||
}
|
||||
|
||||
void _native_init_uart0()
|
||||
{
|
||||
_native_uart_out = STDOUT_FILENO;
|
||||
_native_uart_in = STDIN_FILENO;
|
||||
|
||||
puts("RIOT native uart0 initialized.");
|
||||
}
|
||||
|
||||
int putchar(int c) {
|
||||
write(_native_uart_out, &c, 1);
|
||||
return 0;
|
||||
}
|
||||
|
@ -4,3 +4,5 @@ void _native_handle_uart0_input(void);
|
||||
void _native_init_uart0(void);
|
||||
int _native_set_uart_fds(void);
|
||||
#endif
|
||||
|
||||
void board_init(void);
|
||||
|
@ -31,12 +31,14 @@
|
||||
#include <signal.h>
|
||||
#include <stdint.h>
|
||||
#include <err.h>
|
||||
|
||||
#include "hwtimer.h"
|
||||
#include "hwtimer_arch.h"
|
||||
|
||||
#include "hwtimer_cpu.h"
|
||||
#include "cpu.h"
|
||||
#include "cpu-conf.h"
|
||||
#include "native_internal.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
|
||||
@ -223,7 +225,7 @@ unsigned long hwtimer_arch_now(void)
|
||||
|
||||
DEBUG("hwtimer_arch_now()\n");
|
||||
|
||||
_native_in_syscall = 1;
|
||||
_native_syscall_enter();
|
||||
#ifdef __MACH__
|
||||
clock_serv_t cclock;
|
||||
mach_timespec_t mts;
|
||||
@ -239,7 +241,7 @@ unsigned long hwtimer_arch_now(void)
|
||||
}
|
||||
|
||||
#endif
|
||||
_native_in_syscall = 0;
|
||||
_native_syscall_leave();
|
||||
|
||||
native_hwtimer_now = ts2ticks(&t) - time_null;
|
||||
|
||||
|
@ -27,16 +27,22 @@
|
||||
* http://sourceforge.net/p/predef/wiki/OperatingSystems/
|
||||
*/
|
||||
#ifdef BSD // BSD = (FreeBSD, Darwin, ...)
|
||||
#ifndef _XOPEN_SOURCE
|
||||
#define _XOPEN_SOURCE
|
||||
#elif defined(__linux__)
|
||||
#define __USE_GNU
|
||||
#endif
|
||||
#include <ucontext.h>
|
||||
#ifdef BSD
|
||||
#undef _XOPEN_SOURCE
|
||||
#elif defined(__linux__)
|
||||
#undef __USE_GNU
|
||||
#else
|
||||
#include <ucontext.h>
|
||||
#endif
|
||||
#elif defined(__linux__)
|
||||
#ifndef _GNU_SOURCE
|
||||
#define GNU_SOURCE
|
||||
#include <ucontext.h>
|
||||
#undef GNU_SOURCE
|
||||
#else
|
||||
#include <ucontext.h>
|
||||
#endif
|
||||
#endif // BSD/Linux
|
||||
|
||||
#include "kernel_internal.h"
|
||||
#include "sched.h"
|
||||
@ -62,15 +68,5 @@ int unregister_interrupt(int sig);
|
||||
/* this should be defined elsewhere */
|
||||
void thread_yield(void);
|
||||
|
||||
extern void _native_sig_leave_tramp(void);
|
||||
extern ucontext_t *_native_cur_ctx, *_native_isr_ctx;
|
||||
extern volatile unsigned int _native_saved_eip;
|
||||
extern volatile int _native_in_isr;
|
||||
extern volatile int _native_in_syscall;
|
||||
extern volatile int _native_sigpend;
|
||||
#ifdef MODULE_UART0
|
||||
#include <sys/select.h>
|
||||
extern fd_set _native_rfds;
|
||||
#endif
|
||||
/** @} */
|
||||
#endif //_CPU_H
|
||||
|
57
cpu/native/include/native_internal.h
Normal file
57
cpu/native/include/native_internal.h
Normal file
@ -0,0 +1,57 @@
|
||||
/**
|
||||
* Native CPU internal declarations
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup arch
|
||||
* @defgroup native_cpu Native CPU
|
||||
* @{
|
||||
* @author Ludwig Ortmann <ludwig.ortmann@fu-berlin.de>
|
||||
*/
|
||||
|
||||
#ifndef _NATIVE_INTERNAL_H
|
||||
#define _NATIVE_INTERNAL_H
|
||||
|
||||
//#include <signal.h>
|
||||
|
||||
/**
|
||||
* internal functions
|
||||
*/
|
||||
void native_cpu_init(void);
|
||||
void native_interrupt_init(void);
|
||||
|
||||
void native_irq_handler();
|
||||
extern void _native_sig_leave_tramp(void);
|
||||
|
||||
void _native_syscall_leave();
|
||||
void _native_syscall_enter();
|
||||
|
||||
/**
|
||||
* external functions regularly wrapped in native for direct use
|
||||
*/
|
||||
extern ssize_t (*real_read)(int fd, void *buf, size_t count);
|
||||
extern ssize_t (*real_write)(int fd, const void *buf, size_t count);
|
||||
|
||||
/**
|
||||
* data structures
|
||||
*/
|
||||
extern volatile int native_interrupts_enabled;
|
||||
extern volatile unsigned int _native_saved_eip;
|
||||
extern int _sig_pipefd[2];
|
||||
extern volatile int _native_sigpend;
|
||||
extern volatile int _native_in_isr;
|
||||
extern volatile int _native_in_syscall;
|
||||
|
||||
extern char __isr_stack[SIGSTKSZ];
|
||||
extern char __end_stack[SIGSTKSZ];
|
||||
extern ucontext_t native_isr_context;
|
||||
extern ucontext_t end_context;
|
||||
extern ucontext_t *_native_cur_ctx, *_native_isr_ctx;
|
||||
|
||||
#ifdef MODULE_UART0
|
||||
#include <sys/select.h>
|
||||
extern fd_set _native_rfds;
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
#endif /* _NATIVE_INTERNAL_H */
|
@ -37,7 +37,7 @@ struct rx_buffer_s {
|
||||
char data[NATIVE_MAX_DATA_LENGTH];
|
||||
};
|
||||
|
||||
extern struct rx_buffer_s _nativenet_rx_buffer[];
|
||||
extern struct rx_buffer_s _nativenet_rx_buffer[RX_BUF_SIZE];
|
||||
|
||||
void _nativenet_handle_packet(radio_packet_t *packet);
|
||||
#endif /* NATIVENET_INTERNAL_H */
|
||||
|
@ -13,6 +13,7 @@
|
||||
* @file
|
||||
* @author Ludwig Ortmann <ludwig.ortmann@fu-berlin.de>
|
||||
*/
|
||||
|
||||
#include <err.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
@ -39,24 +40,28 @@
|
||||
|
||||
#include "lpm.h"
|
||||
|
||||
#include "native_internal.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
volatile int native_interrupts_enabled;
|
||||
|
||||
volatile int _native_sigpend;
|
||||
volatile int _native_in_isr;
|
||||
volatile int _native_in_syscall;
|
||||
ucontext_t native_isr_context;
|
||||
static sigset_t native_sig_set;
|
||||
static char __isr_stack[SIGSTKSZ];
|
||||
extern volatile tcb_t *active_thread;
|
||||
|
||||
volatile unsigned int _native_saved_eip;
|
||||
volatile int native_interrupts_enabled;
|
||||
volatile int _native_in_isr;
|
||||
volatile int _native_in_syscall;
|
||||
|
||||
static sigset_t native_sig_set;
|
||||
|
||||
char __isr_stack[SIGSTKSZ];
|
||||
ucontext_t native_isr_context;
|
||||
ucontext_t *_native_cur_ctx, *_native_isr_ctx;
|
||||
|
||||
int *process_heap_address;
|
||||
|
||||
static int pipefd[2];
|
||||
volatile unsigned int _native_saved_eip;
|
||||
volatile int _native_sigpend;
|
||||
int _sig_pipefd[2];
|
||||
|
||||
struct int_handler_t {
|
||||
void (*func)(void);
|
||||
@ -64,10 +69,6 @@ struct int_handler_t {
|
||||
static struct int_handler_t native_irq_handlers[255];
|
||||
char sigalt_stk[SIGSTKSZ];
|
||||
|
||||
|
||||
void native_irq_handler();
|
||||
|
||||
|
||||
void print_thread_sigmask(ucontext_t *cp)
|
||||
{
|
||||
sigset_t *p = &cp->uc_sigmask;
|
||||
@ -149,7 +150,7 @@ unsigned disableIRQ(void)
|
||||
unsigned int prev_state;
|
||||
sigset_t mask;
|
||||
|
||||
_native_in_syscall = 1;
|
||||
_native_syscall_enter();
|
||||
DEBUG("disableIRQ()\n");
|
||||
|
||||
if (_native_in_isr == 1) {
|
||||
@ -179,7 +180,7 @@ unsigned disableIRQ(void)
|
||||
native_interrupts_enabled = 0;
|
||||
|
||||
DEBUG("disableIRQ(): return\n");
|
||||
_native_in_syscall = 0;
|
||||
_native_syscall_leave();
|
||||
|
||||
return prev_state;
|
||||
}
|
||||
@ -191,7 +192,7 @@ unsigned enableIRQ(void)
|
||||
{
|
||||
unsigned int prev_state;
|
||||
|
||||
_native_in_syscall = 1;
|
||||
_native_syscall_enter();
|
||||
DEBUG("enableIRQ()\n");
|
||||
|
||||
if (_native_in_isr == 1) {
|
||||
@ -204,21 +205,7 @@ unsigned enableIRQ(void)
|
||||
|
||||
prev_state = native_interrupts_enabled;
|
||||
native_interrupts_enabled = 1;
|
||||
|
||||
//print_sigmasks();
|
||||
//native_print_signals();
|
||||
if ((_native_sigpend > 0) && (_native_in_isr == 0)) {
|
||||
_native_cur_ctx = (ucontext_t *)active_thread->sp;
|
||||
DEBUG("\n\n\t\treturn from syscall, calling native_irq_handler\n\n");
|
||||
_native_in_syscall = 0;
|
||||
DEBUG("enableIRQ: calling swapcontext()\n");
|
||||
DEBUG("enableIRQ: _native_cur_ctx == %p, _native_isr_ctx == %p\n", _native_cur_ctx, _native_isr_ctx);
|
||||
makecontext(&native_isr_context, native_irq_handler, 0);
|
||||
swapcontext(_native_cur_ctx, _native_isr_ctx);
|
||||
}
|
||||
else {
|
||||
_native_in_syscall = 0;
|
||||
}
|
||||
_native_syscall_leave();
|
||||
|
||||
DEBUG("enableIRQ(): return\n");
|
||||
|
||||
@ -264,16 +251,14 @@ int _native_popsig(void)
|
||||
nleft = sizeof(int);
|
||||
i = 0;
|
||||
|
||||
_native_in_syscall = 1;
|
||||
while ((nleft > 0) && ((nread = read(pipefd[0], ((uint8_t*)&sig) + i, nleft)) != -1)) {
|
||||
while ((nleft > 0) && ((nread = real_read(_sig_pipefd[0], ((uint8_t*)&sig) + i, nleft)) != -1)) {
|
||||
i += nread;
|
||||
nleft -= nread;
|
||||
}
|
||||
|
||||
if (nread == -1) {
|
||||
err(1, "_native_popsig(): read()");
|
||||
err(1, "_native_popsig(): real_read()");
|
||||
}
|
||||
_native_in_syscall = 0;
|
||||
|
||||
return sig;
|
||||
}
|
||||
@ -318,13 +303,14 @@ void native_irq_handler()
|
||||
void native_isr_entry(int sig, siginfo_t *info, void *context)
|
||||
{
|
||||
(void) info; /* unused at the moment */
|
||||
DEBUG("\n\n\t\tnative_isr_entry\n\n");
|
||||
//printf("\n\033[33m\n\t\tnative_isr_entry(%i)\n\n\033[0m", sig);
|
||||
|
||||
/* save the signal */
|
||||
if (write(pipefd[1], &sig, sizeof(int)) == -1) {
|
||||
err(1, "native_isr_entry(): write()");
|
||||
if (real_write(_sig_pipefd[1], &sig, sizeof(int)) == -1) {
|
||||
err(1, "native_isr_entry(): real_write()");
|
||||
}
|
||||
_native_sigpend++;
|
||||
//real_write(STDOUT_FILENO, "sigpend\n", 8);
|
||||
|
||||
makecontext(&native_isr_context, native_irq_handler, 0);
|
||||
_native_cur_ctx = (ucontext_t *)active_thread->sp;
|
||||
@ -332,7 +318,7 @@ void native_isr_entry(int sig, siginfo_t *info, void *context)
|
||||
/* XXX: Workaround safety check - whenever this happens it really
|
||||
* indicates a bug in disableIRQ */
|
||||
if (native_interrupts_enabled == 0) {
|
||||
warnx("interrupts are off, but I caught a signal.");
|
||||
//printf("interrupts are off, but I caught a signal.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -351,11 +337,12 @@ void native_isr_entry(int sig, siginfo_t *info, void *context)
|
||||
((void*)(((ucontext_t *)context)->uc_mcontext.gregs[REG_EIP]))
|
||||
> ((void*)process_heap_address)
|
||||
) {
|
||||
DEBUG("\n\033[36mEIP:\t%p\nHEAP:\t%p\nnot switching\n\n\033[0m", (void*)((ucontext_t *)context)->uc_mcontext.gregs[REG_EIP], (void*)process_heap_address);
|
||||
//printf("\n\033[36mEIP:\t%p\nHEAP:\t%p\nnot switching\n\n\033[0m", (void*)((ucontext_t *)context)->uc_mcontext.gregs[REG_EIP], (void*)process_heap_address);
|
||||
}
|
||||
else {
|
||||
|
||||
_native_in_isr = 1;
|
||||
DEBUG("\n\033[31mEIP:\t%p\nHEAP:\t%p\ngo switching\n\n\033[0m", (void*)((ucontext_t *)context)->uc_mcontext.gregs[REG_EIP], (void*)process_heap_address);
|
||||
//printf("\n\033[31mEIP:\t%p\nHEAP:\t%p\ngo switching\n\n\033[0m", (void*)((ucontext_t *)context)->uc_mcontext.gregs[REG_EIP], (void*)process_heap_address);
|
||||
_native_saved_eip = ((ucontext_t *)context)->uc_mcontext.gregs[REG_EIP];
|
||||
((ucontext_t *)context)->uc_mcontext.gregs[REG_EIP] = (unsigned int)&_native_sig_leave_tramp;
|
||||
}
|
||||
@ -515,13 +502,14 @@ void native_interrupt_init(void)
|
||||
|
||||
_native_in_syscall = 0;
|
||||
|
||||
if (pipe(pipefd) == -1) {
|
||||
if (pipe(_sig_pipefd) == -1) {
|
||||
err(1, "native_interrupt_init(): pipe()");
|
||||
}
|
||||
|
||||
/* allow for ctrl+c to shut down gracefully */
|
||||
register_interrupt(SIGINT, shutdown);
|
||||
|
||||
|
||||
puts("RIOT native interrupts/signals initialized.");
|
||||
}
|
||||
/** @} */
|
||||
|
@ -28,6 +28,8 @@
|
||||
#include "lpm.h"
|
||||
#include "debug.h"
|
||||
#include "cpu.h"
|
||||
|
||||
#include "native_internal.h"
|
||||
#ifdef MODULE_UART0
|
||||
#include "board_internal.h"
|
||||
#endif
|
||||
@ -51,7 +53,10 @@ void _native_lpm_sleep()
|
||||
nfds = _native_set_uart_fds();
|
||||
nfds++;
|
||||
|
||||
_native_in_syscall++; // no switching here
|
||||
nfds = select(nfds, &_native_rfds, NULL, NULL, NULL);
|
||||
_native_in_syscall--;
|
||||
|
||||
DEBUG("_native_lpm_sleep: returned: %i\n", nfds);
|
||||
|
||||
if (nfds != -1) {
|
||||
@ -71,9 +76,8 @@ void _native_lpm_sleep()
|
||||
|
||||
if (_native_sigpend > 0) {
|
||||
DEBUG("\n\n\t\treturn from syscall, calling native_irq_handler\n\n");
|
||||
_native_in_syscall = 0;
|
||||
_native_in_isr = 1;
|
||||
swapcontext(_native_cur_ctx, _native_isr_ctx);
|
||||
_native_in_syscall++;
|
||||
_native_syscall_leave();
|
||||
}
|
||||
}
|
||||
|
||||
@ -98,7 +102,6 @@ enum lpm_mode lpm_set(enum lpm_mode target)
|
||||
case LPM_IDLE:
|
||||
//DEBUG("lpm_set(): pause()\n");
|
||||
|
||||
_native_in_syscall = 1;
|
||||
//pause();
|
||||
_native_lpm_sleep();
|
||||
break;
|
||||
|
@ -42,12 +42,15 @@
|
||||
#include "cpu.h"
|
||||
#include "cpu-conf.h"
|
||||
|
||||
#include "native_internal.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
extern volatile tcb_t *active_thread;
|
||||
static ucontext_t end_context;
|
||||
static char __end_stack[SIGSTKSZ];
|
||||
|
||||
ucontext_t end_context;
|
||||
char __end_stack[SIGSTKSZ];
|
||||
|
||||
#ifdef MODULE_UART0
|
||||
fd_set _native_rfds;
|
||||
@ -104,7 +107,6 @@ char *thread_stack_init(void (*task_func)(void), void *stack_start, int stacksiz
|
||||
void cpu_switch_context_exit(void)
|
||||
{
|
||||
ucontext_t *ctx;
|
||||
extern int native_interrupts_enabled;
|
||||
|
||||
DEBUG("XXX: cpu_switch_context_exit()\n");
|
||||
if ((sched_context_switch_request == 1) || (active_thread == NULL)) {
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "tap.h"
|
||||
#include "nativenet.h"
|
||||
#include "nativenet_internal.h"
|
||||
#include "native_internal.h"
|
||||
|
||||
#define TAP_BUFFER_LENGTH (ETHER_MAX_LEN)
|
||||
int _native_marshall_ethernet(uint8_t *framebuf, radio_packet_t *packet);
|
||||
@ -62,9 +63,7 @@ void _native_handle_tap_input(void)
|
||||
/* TODO: check whether this is an input or an output event
|
||||
TODO: refactor this into general io-signal multiplexer */
|
||||
|
||||
_native_in_syscall = 1;
|
||||
nread = read(_native_tap_fd, &frame, sizeof(union eth_frame));
|
||||
_native_in_syscall = 0;
|
||||
nread = real_read(_native_tap_fd, &frame, sizeof(union eth_frame));
|
||||
DEBUG("_native_handle_tap_input - read %d bytes\n", nread);
|
||||
if (nread > 0) {
|
||||
if (ntohs(frame.field.header.ether_type) == NATIVE_ETH_PROTO) {
|
||||
|
@ -26,6 +26,8 @@
|
||||
#include "rtc.h"
|
||||
#include "cpu.h"
|
||||
|
||||
#include "native_internal.h"
|
||||
|
||||
static int native_rtc_enabled;
|
||||
|
||||
void rtc_init(void)
|
||||
@ -59,24 +61,24 @@ void rtc_get_localtime(struct tm *localt)
|
||||
time_t t;
|
||||
|
||||
if (native_rtc_enabled == 1) {
|
||||
_native_in_syscall++;
|
||||
_native_syscall_enter();
|
||||
t = time(NULL);
|
||||
|
||||
if (localtime_r(&t, localt) == NULL) {
|
||||
err(1, "rtc_get_localtime: localtime_r");
|
||||
}
|
||||
_native_in_syscall--;
|
||||
_native_syscall_leave();
|
||||
}
|
||||
}
|
||||
|
||||
time_t rtc_time(struct timeval *time)
|
||||
{
|
||||
if (native_rtc_enabled == 1) {
|
||||
_native_in_syscall++;
|
||||
_native_syscall_enter();
|
||||
if (gettimeofday(time, NULL) == -1) {
|
||||
err(1, "rtc_time: gettimeofday");
|
||||
}
|
||||
_native_in_syscall--;
|
||||
_native_syscall_leave();
|
||||
}
|
||||
return time->tv_sec;
|
||||
}
|
||||
|
@ -14,21 +14,29 @@
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#include <dlfcn.h>
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <err.h>
|
||||
|
||||
#include <kernel_internal.h>
|
||||
#include <cpu.h>
|
||||
|
||||
#include "kernel_internal.h"
|
||||
#include "cpu.h"
|
||||
|
||||
#include "native_internal.h"
|
||||
#include "tap.h"
|
||||
|
||||
extern void board_init(void);
|
||||
extern void native_cpu_init(void);
|
||||
extern void native_interrupt_init(void);
|
||||
|
||||
__attribute__((constructor)) static void startup(int argc, char **argv)
|
||||
{
|
||||
/* get system read/write */
|
||||
*(void **)(&real_read) = dlsym(RTLD_NEXT, "read");
|
||||
*(void **)(&real_write) = dlsym(RTLD_NEXT, "write");
|
||||
|
||||
#ifdef MODULE_NATIVENET
|
||||
if (argc < 2) {
|
||||
|
154
cpu/native/syscalls.c
Normal file
154
cpu/native/syscalls.c
Normal file
@ -0,0 +1,154 @@
|
||||
/**
|
||||
* Native CPU syscall managing
|
||||
*
|
||||
* Wrap system calls and system call invoking library calls to make
|
||||
* sure no context switches happen during a system call.
|
||||
*
|
||||
* Copyright (C) 2013 Ludwig Ortmann
|
||||
*
|
||||
* This file subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*
|
||||
* @ingroup native_cpu
|
||||
* @{
|
||||
* @file
|
||||
* @author Ludwig Ortmann <ludwig.ortmann@fu-berlin.de>
|
||||
*/
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#include <dlfcn.h>
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#include <err.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "cpu.h"
|
||||
|
||||
#include "native_internal.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
extern volatile tcb_t *active_thread;
|
||||
|
||||
ssize_t (*real_read)(int fd, void *buf, size_t count);
|
||||
ssize_t (*real_write)(int fd, const void *buf, size_t count);
|
||||
|
||||
void _native_syscall_enter()
|
||||
{
|
||||
_native_in_syscall++;
|
||||
DEBUG("> _native_in_syscall: %d\n", _native_in_syscall);
|
||||
}
|
||||
|
||||
void _native_syscall_leave()
|
||||
{
|
||||
_native_in_syscall--;
|
||||
DEBUG("< _native_in_syscall: %d\n", _native_in_syscall);
|
||||
if ((_native_sigpend > 0) && (_native_in_isr == 0) && (_native_in_syscall == 0)) {
|
||||
_native_in_isr = 1;
|
||||
_native_cur_ctx = (ucontext_t *)active_thread->sp;
|
||||
makecontext(&native_isr_context, native_irq_handler, 0);
|
||||
swapcontext(_native_cur_ctx, &native_isr_context);
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t read(int fd, void *buf, size_t count)
|
||||
{
|
||||
ssize_t r;
|
||||
|
||||
_native_syscall_enter();
|
||||
r = real_read(fd, buf, count);
|
||||
_native_syscall_leave();
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
ssize_t write(int fd, const void *buf, size_t count)
|
||||
{
|
||||
ssize_t r;
|
||||
|
||||
_native_syscall_enter();
|
||||
//real_write(fd, "real_write: ", 12);
|
||||
r = real_write(fd, buf, count);
|
||||
_native_syscall_leave();
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int putchar(int c) {
|
||||
write(STDOUT_FILENO, &c, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int puts(const char *s)
|
||||
{
|
||||
int r;
|
||||
r = write(STDOUT_FILENO, (char*)s, strlen(s));
|
||||
putchar('\n');
|
||||
return r;
|
||||
}
|
||||
|
||||
char *make_message(const char *format, va_list argp)
|
||||
{
|
||||
int n;
|
||||
int size = 100;
|
||||
char *message, *temp;
|
||||
|
||||
if ((message = malloc(size)) == NULL)
|
||||
return NULL;
|
||||
|
||||
while (1) {
|
||||
n = vsnprintf(message, size, format, argp);
|
||||
if (n < 0)
|
||||
return NULL;
|
||||
if (n < size)
|
||||
return message;
|
||||
size = n + 1;
|
||||
if ((temp = realloc(message, size)) == NULL) {
|
||||
free(message);
|
||||
return NULL;
|
||||
} else {
|
||||
message = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int printf(const char *format, ...)
|
||||
{
|
||||
int r;
|
||||
va_list argp;
|
||||
char *m;
|
||||
|
||||
va_start(argp, format);
|
||||
if ((m = make_message(format, argp)) == NULL) {
|
||||
err(EXIT_FAILURE, "malloc");
|
||||
}
|
||||
r = write(STDOUT_FILENO, m, strlen(m));
|
||||
va_end(argp);
|
||||
free(m);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
int vprintf(const char *format, va_list argp)
|
||||
{
|
||||
int r;
|
||||
char *m;
|
||||
|
||||
if ((m = make_message(format, argp)) == NULL) {
|
||||
err(EXIT_FAILURE, "malloc");
|
||||
}
|
||||
r = write(STDOUT_FILENO, m, strlen(m));
|
||||
free(m);
|
||||
|
||||
return r;
|
||||
}
|
Loading…
Reference in New Issue
Block a user