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:
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user