Implementing syscall invocation sequence for ARMv7 architecture.

Removing dependencies to third-party libc routine implementations.
Introducing __TARGET_HOST define for host (non-MCU) builds.
This commit is contained in:
Ruben Ayrapetyan
2014-10-16 18:36:55 +04:00
parent 90789453ba
commit 9c3c835a7e
11 changed files with 156 additions and 213 deletions
-21
View File
@@ -23,7 +23,6 @@
typedef void _FILE;
#ifdef LIBC_RAW
/**
* stdin file descriptor
*/
@@ -38,26 +37,6 @@ typedef void _FILE;
* stderr file descriptor
*/
#define LIBC_STDERR (_FILE*)2
#else /* !LIBC_RAW */
extern const _FILE **libc_stdin;
extern const _FILE **libc_stdout;
extern const _FILE **libc_stderr;
/**
* stdin file descriptor
*/
#define LIBC_STDIN ((_FILE*)*libc_stdin)
/**
* stdout file descriptor
*/
#define LIBC_STDOUT ((_FILE*)*libc_stdout)
/**
* stderr file descriptor
*/
#define LIBC_STDERR ((_FILE*)*libc_stderr)
#endif /* !LIBC_RAW */
extern void* __memset (void *s, int c, size_t n);
extern int __memcmp (const void *s1, const void *s2, size_t n);
+77
View File
@@ -0,0 +1,77 @@
/* Copyright 2014 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ASM_ARM_H
#define ASM_ARM_H
/*
* mov syscall_no -> %r7
* mov arg1 -> %r0
* svc
* mov %r0 -> ret
*/
#define SYSCALL_1(syscall_no, arg1, ret) \
__asm volatile ("mov r0, %[arg1]\n" \
"mov r7, %[syscall_no]\n" \
"svc #0\n" \
"mov %[ret], r0\n" \
: [ret] "=r" (ret) \
: [syscall_no] "r" (syscall_no), [arg1] "r" (arg1) \
: "r0", "r1", "r2", "r3", "r7", "r9", "memory");
/*
* mov syscall_no -> %r7
* mov arg1 -> %r0
* mov arg2 -> %r1
* syscall
* mov %r0 -> ret
*/
#define SYSCALL_2(syscall_no, arg1, arg2, ret) \
__asm volatile ("mov r0, %[arg1]\n" \
"mov r1, %[arg2]\n" \
"mov r7, %[syscall_no]\n" \
"svc #0\n" \
"mov %[ret], r0\n" \
: [ret] "=r" (ret) \
: [syscall_no] "r" (syscall_no), [arg1] "r" (arg1), [arg2] "r" (arg2) \
: "r0", "r1", "r2", "r3", "r7", "r9", "memory");
/*
* mov syscall_no -> %r7
* mov arg1 -> %r0
* mov arg2 -> %r1
* mov arg3 -> %r2
* syscall
* mov %r0 -> ret
*/
#define SYSCALL_3(syscall_no, arg1, arg2, arg3, ret) \
__asm volatile ("mov r0, %[arg1]\n" \
"mov r1, %[arg2]\n" \
"mov r2, %[arg3]\n" \
"mov r7, %[syscall_no]\n" \
"svc #0\n" \
"mov %[ret], r0\n" \
: [ret] "=r" (ret) \
: [syscall_no] "r" (syscall_no), [arg1] "r" (arg1), [arg2] "r" (arg2), [arg3] "r" (arg3) \
: "r0", "r1", "r2", "r3", "r7", "r9", "memory");
#define _START \
bl main; \
\
bl __exit; \
1: \
b 1b
#endif /* !ASM_ARM_H */
+7 -5
View File
@@ -13,8 +13,8 @@
* limitations under the License.
*/
#ifndef LINUX_X64_ASM_H
#define LINUX_X64_ASM_H
#ifndef ASM_X64_H
#define ASM_X64_H
/*
* mov syscall_no -> %rax
@@ -45,7 +45,7 @@
* mov syscall_no -> %rax
* mov arg1 -> %rdi
* mov arg2 -> %rsi
* mov arg2 -> %rdx
* mov arg3 -> %rdx
* syscall
* mov %rax -> ret
*/
@@ -62,6 +62,8 @@
callq main; \
\
mov %rax, %rdi; \
callq __exit;
callq __exit; \
1: \
jmp 1b
#endif /* !LINUX_X64_ASM_H */
#endif /* !ASM_X64_H */
+7 -5
View File
@@ -13,8 +13,8 @@
* limitations under the License.
*/
#ifndef LINUX_X86_ASM_H
#define LINUX_X86_ASM_H
#ifndef ASM_X86_H
#define ASM_X86_H
FIXME(Implement x86 ABI);
#error "Not implemented"
@@ -48,7 +48,7 @@ FIXME(Implement x86 ABI);
* mov syscall_no -> %rax
* mov arg1 -> %rdi
* mov arg2 -> %rsi
* mov arg2 -> %rdx
* mov arg3 -> %rdx
* syscall
* mov %rax -> ret
*/
@@ -65,6 +65,8 @@ FIXME(Implement x86 ABI);
callq main; \
\
mov %rax, %rdi; \
callq __exit;
callq __exit; \
1: \
jmp 1b
#endif /* !LINUX_X86_ASM_H */
#endif /* !ASM_X86_H */
+34 -161
View File
@@ -24,22 +24,29 @@
#include <sys/resource.h>
#ifdef LIBC_RAW
#ifdef __TARGET_HOST_x64
# include "asm_x64.h"
#elif defined (__TARGET_HOST_x86)
# include "asm_x86.h"
#endif /* !__TARGET_HOST_x64 && TARGET_HOST_x86 */
#elif defined (__TARGET_HOST_ARMv7)
# include "asm_arm.h"
#else /* !__TARGET_HOST_x64 && !__TARGET_HOST_x86 && !__TARGET_HOST_ARMv7 */
# error "!__TARGET_HOST_x64 && !__TARGET_HOST_x86 && !__TARGET_HOST_ARMv7 "
#endif /* !__TARGET_HOST_x64 && !__TARGET_HOST_x86 && !__TARGET_HOST_ARMv7 */
FIXME(Rename __unused)
#undef __unused
#include <linux/fs.h>
#include <syscall.h>
#include <sys/stat.h>
#include <fcntl.h>
FIXME (/* Include linux/fs.h */)
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
/**
* Exit program with ERR_SYSCALL if syscall_ret_val is negative
*/
@@ -58,7 +65,7 @@ static long int syscall_3 (long int syscall_no, long int arg1, long int arg2, lo
*
* @return syscall's return value
*/
static long int
static __noinline long int
syscall_1 (long int syscall_no, /**< syscall number */
long int arg1) /**< argument */
{
@@ -76,7 +83,7 @@ syscall_1 (long int syscall_no, /**< syscall number */
*
* @return syscall's return value
*/
static long int
static __noinline long int
syscall_2 (long int syscall_no, /**< syscall number */
long int arg1, /**< first argument */
long int arg2) /**< second argument */
@@ -95,7 +102,7 @@ syscall_2 (long int syscall_no, /**< syscall number */
*
* @return syscall's return value
*/
static long int
static __noinline long int
syscall_3 (long int syscall_no, /**< syscall number */
long int arg1, /**< first argument */
long int arg2, /**< second argument */
@@ -357,169 +364,35 @@ void
jrt_set_mem_limits (size_t data_size, /**< limit for data + bss + brk heap */
size_t stack_size) /**< limit for stack */
{
struct rlimit data_limit = { data_size, data_size };
struct rlimit stack_limit = { stack_size, stack_size };
struct
{
unsigned long long rlim_cur;
unsigned long long rlim_max;
} data_limit = { data_size, data_size };
struct
{
unsigned long long rlim_cur;
unsigned long long rlim_max;
} stack_limit = { stack_size, stack_size };
long int ret;
#ifdef __TARGET_HOST_x64
ret = syscall_2 (__NR_setrlimit, RLIMIT_DATA, (intptr_t) &data_limit);
JERRY_ASSERT (ret == 0);
ret = syscall_2 (__NR_setrlimit, RLIMIT_STACK, (intptr_t) &stack_limit);
JERRY_ASSERT (ret == 0);
} /* jrt_set_mem_limits */
#elif defined (LIBC_MUSL)
#include <stdio.h>
#include <stdlib.h>
const _FILE **libc_stdin = (void*)&stdin;
const _FILE **libc_stdout = (void*)&stdout;
const _FILE **libc_stderr = (void*)&stderr;
/** Output of character. Writes the character c, cast to an unsigned char, to stdout. */
int
__putchar (int c)
{
return putchar (c);
} /* __putchar */
/**
* Exit - cause normal process termination with specified status code
*/
void __noreturn
__exit (int status) /**< status code */
{
exit (status);
while (true)
{
/* unreachable */
}
} /* __exit */
/**
* fopen
*
* @return _FILE pointer - upon successful completion,
* NULL - otherwise
*/
_FILE*
__fopen (const char *path, /**< file path */
const char *mode) /**< file open mode */
{
return fopen (path, mode);
} /* __fopen */
/** The rewind () function sets the file position
indicator for the stream pointed to by STREAM to the beginning of the file. */
void
__rewind (_FILE *stream)
{
rewind (stream);
}
/**
* fclose
*
* @return 0 - upon successful completion,
* non-zero value - otherwise.
*/
int
__fclose (_FILE *fp) /**< stream pointer */
{
return fclose (fp);
} /* __fclose */
/**
* fseek
*/
int
__fseek (_FILE * fp, /**< stream pointer */
long offset, /**< offset */
_whence_t whence) /**< specifies position type
to add offset to */
{
int whence_real = SEEK_CUR;
switch (whence)
{
case __SEEK_SET:
{
whence_real = SEEK_SET;
break;
}
case __SEEK_CUR:
{
whence_real = SEEK_CUR;
break;
}
case __SEEK_END:
{
whence_real = SEEK_END;
break;
}
}
return fseek (fp, offset, whence_real);
} /* __fseek */
/**
* ftell
*/
long
__ftell (_FILE * fp) /**< stream pointer */
{
return ftell (fp);
} /* __ftell */
/**
* fread
*
* @return number of bytes read
*/
size_t
__fread (void *ptr, /**< address of buffer to read to */
size_t size, /**< size of elements to read */
size_t nmemb, /**< number of elements to read */
_FILE *stream) /**< stream pointer */
{
return fread (ptr, size, nmemb, stream);
} /* __fread */
/**
* fwrite
*
* @return number of bytes written
*/
size_t
__fwrite (const void *ptr, /**< data to write */
size_t size, /**< size of elements to write */
size_t nmemb, /**< number of elements */
_FILE *stream) /**< stream pointer */
{
return fwrite (ptr, size, nmemb, stream);
} /* __fwrite */
/**
* Setup new memory limits
*/
void
jrt_set_mem_limits (size_t data_size, /**< limit for data + bss + brk heap */
size_t stack_size) /**< limit for stack */
{
struct rlimit data_limit = { data_size, data_size };
struct rlimit stack_limit = { stack_size, stack_size };
int ret;
ret = setrlimit (RLIMIT_DATA, &data_limit);
#elif defined (__TARGET_HOST_ARMv7)
ret = syscall_3 (__NR_prlimit64, 0, RLIMIT_DATA, (intptr_t) &data_limit);
JERRY_ASSERT (ret == 0);
ret = setrlimit (RLIMIT_STACK, &stack_limit);
ret = syscall_3 (__NR_prlimit64, 0, RLIMIT_STACK, (intptr_t) &stack_limit);
JERRY_ASSERT (ret == 0);
#elif defined (__TARGET_HOST_x86)
# error "__TARGET_HOST_x86 case is not implemented"
#else /* !__TARGET_HOST_x64 && !__TARGET_HOST_ARMv7 && !__TARGET_HOST_x86 */
# error "!__TARGET_HOST_x64 && !__TARGET_HOST_ARMv7 && !__TARGET_HOST_x86"
#endif /* !__TARGET_HOST_x64 && !__TARGET_HOST_ARMv7 && !__TARGET_HOST_x86 */
} /* jrt_set_mem_limits */
#else /* !LIBC_RAW && !LIBC_MUSL */
# error "!LIBC_RAW && !LIBC_MUSL"
#endif /* !LIBC_RAW && !LIBC_MUSL */
+5 -5
View File
@@ -2,15 +2,15 @@
# include "asm_x64.h"
#elif defined (__TARGET_HOST_x86)
# include "asm_x86.h"
#else /* !__HOST && !__TARGET_HOST_x86 */
# error "!__HOST && !__TARGET_HOST_x86"
#endif /* !__HOST && !__TARGET_HOST_x86 */
#elif defined (__TARGET_HOST_ARMv7)
# include "asm_arm.h"
#else /* !__TARGET_HOST_x64 && !__TARGET_HOST_x86 && !__TARGET_HOST_ARMv7 */
# error "!__TARGET_HOST_x64 && !__TARGET_HOST_x86 && !__TARGET_HOST_ARMv7"
#endif /* !__TARGET_HOST_x64 && !__TARGET_HOST_x86 && !__TARGET_HOST_ARMv7 */
#ifdef LIBC_RAW
.global _start
_start:
_START
1:
jmp 1b
.end _start
#endif /* LIBC_RAW */